Перейти к основному содержимому

Введение в JSON-Java (org.json)

· 10 мин. чтения

1. Обзор

JSON (нотация объектов JavaScript) — это упрощенный формат обмена данными, и мы чаще всего используем его для связи клиент-сервер. Его легко читать и писать, и он не зависит от языка. Значение JSON может быть другим объектом JSON , массивом , числом , строкой , логическим значением (true/false) или null .

В этом руководстве мы увидим, как создавать, обрабатывать и анализировать JSON с помощью одной из доступных библиотек обработки JSON — библиотеки JSON-Java , также известной как org.json .

2. Обязательное условие

Сначала нам нужно добавить следующую зависимость в наш pom.xml :

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>

Последнюю версию можно найти в Maven Central Repository .

Обратите внимание, что этот пакет уже включен в Android SDK, поэтому мы не должны включать его при его использовании.

3. JSON в Java [пакет org.json]

Библиотека JSON-Java , также известная как org.json (не путать с org.json.simple от Google ), предоставляет нам классы, которые используются для анализа и управления JSON в Java.

Кроме того, эта библиотека также может конвертировать между JSON, XML, заголовками HTTP, файлами cookie, списком с разделителями-запятыми или текстом и т. д.

В этом уроке мы рассмотрим следующие классы:

  1. JSONObject - похож на родной Map - подобный объект Java, который хранит неупорядоченные пары ключ-значение
  2. JSONArray — упорядоченная последовательность значений, похожая на нативную реализацию Vector в Java.
  3. JSONTokener — инструмент, который разбивает фрагмент текста на серию токенов , которые могут использоваться JSONObject или JSONArray для анализа строк JSON
  4. CDL - инструмент, который предоставляет методы для преобразования текста с разделителями-запятыми в JSONArray и наоборот
  5. Cookie — преобразует строку JSON в файлы cookie и наоборот.
  6. HTTP — используется для преобразования из строки JSON в заголовки HTTP и наоборот.
  7. JSONException — стандартное исключение, создаваемое этой библиотекой.

4. JSONОбъект

JSONObject — это неупорядоченный набор пар ключ-значение, напоминающий собственные реализации Map в Java .

  • Ключи — это уникальные строки , которые не могут быть нулевыми .
  • Значения могут быть любыми: от Boolean , Number , String или JSONArray до даже объекта JSONObject.NULL .
  • JSONObject может быть представлен строкой , заключенной в фигурные скобки, с ключами и значениями, разделенными двоеточием, и парами, разделенными запятой.
  • У него есть несколько конструкторов, с помощью которых можно создать JSONObject .

Он также поддерживает следующие основные методы:

  1. get(String key) — получает объект, связанный с предоставленным ключом, выдает JSONException , если ключ не найден
  2. opt(String key) – получает объект, связанный с предоставленным ключом, в противном случае null
  3. put(String key, Object value) — вставляет или заменяет пару ключ-значение в текущем JSONObject.

Метод put() — это перегруженный метод, который принимает ключ типа String и несколько типов в качестве значения.

Полный список методов, поддерживаемых JSONObject , см. в официальной документации.

Давайте теперь обсудим некоторые основные операции, поддерживаемые этим классом.

4.1. Создание JSON непосредственно из JSONObject

JSONObject предоставляет API, аналогичный интерфейсу Map в Java .

Мы можем использовать метод put() и указать ключ и значение в качестве аргумента:

JSONObject jo = new JSONObject();
jo.put("name", "jon doe");
jo.put("age", "22");
jo.put("city", "chicago");

Теперь наш JSONObject будет выглядеть так:

{"city":"chicago","name":"jon doe","age":"22"}

Существует семь различных перегруженных сигнатур метода JSONObject.put() . Хотя ключ может быть только уникальной, ненулевой строкой, значение может быть любым.

4.2. Создание JSON из карты

Вместо того, чтобы напрямую помещать ключ и значения в JSONObject , мы можем создать пользовательскую карту , а затем передать ее в качестве аргумента конструктору JSONObject .

Этот пример даст те же результаты, что и выше:

Map<String, String> map = new HashMap<>();
map.put("name", "jon doe");
map.put("age", "22");
map.put("city", "chicago");
JSONObject jo = new JSONObject(map);

4.3. Создание JSONObject из строки JSON ``

Чтобы преобразовать строку JSON в объект JSON , мы можем просто передать строку конструктору.

Этот пример даст те же результаты, что и выше:

JSONObject jo = new JSONObject(
"{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}"
);

Переданный аргумент String должен быть допустимым JSON; в противном случае этот конструктор может вызвать JSONException .

4.4. Сериализировать объект Java в JSON

Один из конструкторов JSONObject принимает POJO в качестве аргумента. В приведенном ниже примере пакет использует геттеры из класса DemoBean и создает для них соответствующий объект JSONObject .

Чтобы получить JSONObject из объекта Java, нам нужно использовать класс, который является допустимым Java Bean :

DemoBean demo = new DemoBean();
demo.setId(1);
demo.setName("lorem ipsum");
demo.setActive(true);

JSONObject jo = new JSONObject(demo);

А вот JSONObject jo :

{"name":"lorem ipsum","active":true,"id":1}

Хотя у нас есть способ сериализовать объект Java в строку JSON, нет возможности преобразовать его обратно с помощью этой библиотеки. Если нам нужна такая гибкость, мы можем переключиться на другие библиотеки, такие как Jackson .

5. Массив JSON

JSONArray — это упорядоченный набор значений, напоминающий собственную реализацию Vector в Java .

  • Значения могут быть любыми: от Number , String , Boolean , JSONArray или JSONObject до даже объекта JSONObject.NULL .
  • Он представлен строкой , заключенной в квадратные скобки, и состоит из набора значений, разделенных запятыми.
  • Как и JSONObject , он имеет конструктор, который принимает исходную строку и анализирует ее для создания JSONArray .

Это основные методы класса JSONArray :

  1. get(int index) — возвращает значение по указанному индексу (от 0 до общей длины — 1), в противном случае генерирует JSONException
  2. opt(int index) – возвращает значение, связанное с индексом (от 0 до общей длины – 1). Если в этом индексе нет значения, возвращается нуль .
  3. put(значение объекта) — добавить значение объекта к этому массиву JSONArray. Этот метод перегружен и поддерживает широкий спектр типов данных.

Полный список методов, поддерживаемых JSONArray, можно найти в официальной документации .

5.1. Создание массива JSON

После инициализации объекта JSONArray мы можем просто добавлять и извлекать элементы с помощью методов put() и get() :

JSONArray ja = new JSONArray();
ja.put(Boolean.TRUE);
ja.put("lorem ipsum");

JSONObject jo = new JSONObject();
jo.put("name", "jon doe");
jo.put("age", "22");
jo.put("city", "chicago");

ja.put(jo);

Ниже приведено содержимое нашего JSONArray (код отформатирован для ясности):

[
true,
"lorem ipsum",
{
"city": "chicago",
"name": "jon doe",
"age": "22"
}
]

5.2. Создание JSONArray непосредственно из строки JSON

Как и JSONObject , JSONArray также имеет конструктор, который создает объект Java непосредственно из строки JSON :

JSONArray ja = new JSONArray("[true, \"lorem ipsum\", 215]");

Этот конструктор может вызвать исключение JSONException , если исходная строка не является допустимой строкой JSON .

5.3. Создание JSONArray непосредственно из коллекции или массива

Конструктор JSONArray также поддерживает объекты коллекции и массива в качестве аргументов.

Мы просто передаем их в качестве аргумента конструктору, и он возвращает объект JSONArray :

List<String> list = new ArrayList<>();
list.add("California");
list.add("Texas");
list.add("Hawaii");
list.add("Alaska");

JSONArray ja = new JSONArray(list);

Теперь наш JSONArray состоит из следующего:

["California","Texas","Hawaii","Alaska"]

6. Токенер JSON

JSONTokener принимает исходную строку в качестве входных данных для своего конструктора и извлекает из нее символы и токены. Он используется внутри классами этого пакета (такими как JSONObject , JSONArray ) для разбора строк JSON .

Может быть не так много ситуаций, когда мы будем напрямую использовать этот класс, поскольку мы можем добиться той же функциональности, используя другие более простые методы (например, string.toCharArray() ):

JSONTokener jt = new JSONTokener("lorem");

while(jt.more()) {
Log.info(jt.next());
}

Теперь мы можем получить доступ к JSONTokener как к итератору, используя метод more() для проверки наличия оставшихся элементов и метод next() для доступа к следующему элементу.

Вот токены, полученные из предыдущего примера:

l
o
r
e
m

7. КДЛ

Нам предоставляется класс CDL (список с разделителями-запятыми) для преобразования текста с разделителями-запятыми в JSONArray и наоборот.

7.1. Создание JSONArray непосредственно из текста с разделителями - запятыми

Чтобы создать JSONArray непосредственно из текста, разделенного запятыми, мы можем использовать статический метод rowToJSONArray() , который принимает JSONTokener :

JSONArray ja = CDL.rowToJSONArray(new JSONTokener("England, USA, Canada"));

Вот из чего сейчас состоит наш JSONArray :

["England","USA","Canada"]

7.2. Создание текста с разделителями-запятыми из JSONArray

Давайте посмотрим, как отменить предыдущий шаг и вернуть текст с разделителями-запятыми из JSONArray :

JSONArray ja = new JSONArray("[\"England\",\"USA\",\"Canada\"]");
String cdt = CDL.rowToString(ja);

String cdt теперь содержит следующее:

England,USA,Canada

7.3. Создание JSONArray из JSONObject с использованием текста с разделителями -запятыми

Чтобы создать JSONArray из JSONObject s, мы будем использовать текстовую строку , содержащую как заголовки, так и данные, разделенные запятыми.

Мы разделяем разные строки, используя возврат каретки (\r) или перевод строки (\n).

Первая строка интерпретируется как список заголовков, а все последующие строки обрабатываются как данные:

String string = "name, city, age \n" +
"john, chicago, 22 \n" +
"gary, florida, 35 \n" +
"sal, vegas, 18";

JSONArray result = CDL.toJSONArray(string);

Результат объекта JSONArray теперь состоит из следующего (выходной формат отформатирован для ясности):

[
{
"name": "john",
"city": "chicago",
"age": "22"
},
{
"name": "gary",
"city": "florida",
"age": "35"
},
{
"name": "sal",
"city": "vegas",
"age": "18"
}
]

Обратите внимание, что и данные, и заголовок были предоставлены в одной и той же строке String . У нас есть альтернативный способ сделать это, где мы можем добиться той же функциональности, предоставив JSONArray , чтобы заголовки и строка с разделителями-запятыми работали как данные.

Опять же, мы разделяем разные строки, используя возврат каретки (\r) или перевод строки (\n) :

JSONArray ja = new JSONArray();
ja.put("name");
ja.put("city");
ja.put("age");

String string = "john, chicago, 22 \n"
+ "gary, florida, 35 \n"
+ "sal, vegas, 18";

JSONArray result = CDL.toJSONArray(ja, string);

Здесь мы получим содержимое результата объекта точно так же, как и раньше.

8. Печенье

Класс Cookie имеет дело с файлами cookie веб-браузера и имеет методы для преобразования файла cookie браузера в JSONObject и наоборот.

Вот основные методы класса Cookie :

  1. toJsonObject(String sourceCookie) — преобразует строку cookie в JSONObject.
  2. toString(JSONObject jo) — обратный предыдущему методу, преобразует JSONObject в строку cookie. ``

Чтобы преобразовать строку cookie в JSONObject , мы будем использовать статический метод Cookie.toJSONObject() :

String cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";
JSONObject cookieJO = Cookie.toJSONObject(cookie);

Теперь мы преобразуем JSONObject в строку cookie . Это обратная сторона предыдущего шага:

String cookie = Cookie.toString(cookieJO);

9. HTTP

Класс HTTP содержит статические методы, которые используются для преобразования заголовков HTTP в JSONObject и наоборот.

Этот класс также имеет два основных метода:

  1. toJsonObject (String sourceHttpHeader) — преобразует строку HttpHeader в JSONObject.
  2. toString(JSONObject jo) — преобразует предоставленный JSONObject в строку .

9.1. Преобразование JSONObject в заголовок HTTP

Метод HTTP.toString() используется для преобразования JSONObject в строку заголовка HTTP :

JSONObject jo = new JSONObject();
jo.put("Method", "POST");
jo.put("Request-URI", "http://www.example.com/");
jo.put("HTTP-Version", "HTTP/1.1");
String httpStr = HTTP.toString(jo);

Вот из чего будет состоять наша строка httpStr :

POST "http://www.example.com/" HTTP/1.1

Обратите внимание, что при преобразовании заголовка HTTP-запроса JSONObject должен содержать ключи «Method» , «Request-URI» и «HTTP-Version» . А для заголовка ответа объект должен содержать параметры «HTTP-Version» , «Status-Code» и «Reason-Phrase» .

9.2. Преобразование строки заголовка HTTP обратно в JSONObject

Здесь мы преобразуем строку HTTP, полученную на предыдущем шаге, обратно в тот самый JSONObject , который мы создали на этом шаге:

JSONObject obj = HTTP.toJSONObject("POST \"http://www.example.com/\" HTTP/1.1");

10. Исключение JSON

JSONException — это стандартное исключение, создаваемое этим пакетом всякий раз, когда возникает какая-либо ошибка.

Это используется во всех классах из этого пакета. Исключение обычно сопровождается сообщением, в котором указывается, что именно пошло не так.

11. Заключение

В этой статье мы рассмотрели JSON с использованием Java — org.json — и сосредоточились на некоторых основных функциях, доступных здесь.

Полные фрагменты кода, использованные в этой статье, можно найти на GitHub .