Избранное сообщение

Фетісов В. С. Комп’ютерні технології в тестуванні. Навчально-методичний посібник. 2-ге видання, перероблене та доповнене / Мои публикации

В 10-х годах я принимал участие в программе Европейского Союза Tempus "Освітні вимірювання, адаптовані до стандартів ЄС". В рамк...

Благодаря Интернету количество писателей и поэтов увеличивается в геометрической прогрессии. Поголовье читателей начинает заметно отставать.

среда, 27 апреля 2016 г.

Шпаргалка Java программиста 8. Библиотеки для работы с Json (Gson, Fastjson, LoganSquare, Jackson, JsonPath и другие) / Программирование на Java

В одной из моих прошлых статей я рассказывал о своем opensorce pet проекте useful-java-links, идея которого собрать как можно больше ссылок на полезные Java библиотеки и фреймворки. У него так же есть подпроект Hello World project идея которого для каждой библиотеки собрать несколько простых примеров её использования.

Проблема программистов в Java мире в том что кроме стандартной библиотеки JDK есть огромное других полезных библиотек, причем переход от одной библиотеки к другой может вызывать проблемы из-за неполной документации, отсутствия простых примеров или даже сложности понять какие зависимости нужно добавить в maven чтобы все запустилось. А на новой работе вполне могут использовать вместо твоей любимой библиотеки ту которую ты не знаешь. Идея моего проекта облегчить изучение и выбор разных библиотек.

Общее оглавление 'Шпаргалок'

Итак, давайте посмотрим какие известные библиотеки есть для работы с JSON в Java…

Цитата из useful-java-links:


Итак, у нас восемь библиотек для сериализации и десериализации в json, две библиотеки для генерации Java классов по схеме или json файлу, одна библиотека для валидации схемы и два аналога XPath, но для json. Давайте рассмотрим каждую из них.

1. JSON парсеры


Существует три основных способа сериализации и десериализации среди указанных библиотек (от самого простого к самому сложному) и один дополнительный:

  1. Data bind,
  2. Tree Model,
  3. Streaming API,
  4. (И дополнительный способ) Аналоги XPath,

Давайте рассмотрим с чем их едят:

  1. Data bind самый популярный и простой способ, вы просто указываете класс, который нужно преобразовать в json, может быть часть полей отмечаете аннотациями (а зачастую даже это необязательно), а библиотека сама превращает этот класс и всю его иерархию классов в json. Аналогом при работе с xml будет JAXB (Java Architecture for XML Binding)
    Плюсы: наиболее простой из всех, по сути главное реализовать только Java классы, более того можно просто сгенерировать Java классы из json'a или json схемы.
    Минусы: скорость и память. Большинство библиотек использует рефлексию и т.п. методы работы с Java классами (хотя не все), что очевидно не очень быстро. К тому же, весь json файл сразу превращается в Java объекты, что может просто исчерпать всю доступную память, если вы попытаетесь обработать очень большой json.
    Вывод: если нет проблем с производительностью, памятью и вы не собираетесь обрабатывать многогигабайтные json'ы скорее всего самый лучший способ.
  2. Tree Model — данный парсер представляет json в виде Java классов таких как Node или JsonElement c иерархической структурой, а уже сам программист их обходит и получает из них информацию. Данный способ похож на DOM парсеры в xml.
    Плюсы: обычно быстрее первого способа и проще третьего,
    Минусы: уступает Data bind по простоте, плюс ряд библиотек способен генерить классы при Data bind, а не использовать рефлексию, в этом случае то что Tree Model будет быстрее не очевидно, к тому же не решается проблема огромных файлов и ограничения памяти.
  3. Streaming API — самый низкоуровневый способ, по сути программист сам вручную разбирает токены json'a. Зато никаких ограничений по памяти и в теории максимальная производительность.
    Плюсы: производительность и минимальное потребление памяти,
    Минусы: сложность использования,
  4. Аналоги XPath — дополнительный способ, не очень подходит, если нужно получит всю информацию из json'a, зато позволяет написав выражение$.store.book[*].author и получить список всех авторов всех книг из json'a магазина. То есть легко получать часть информации из json'а.
    Плюсы: позволяет быстро получить информацию из json'а по сложным критериям,
    Минусы: не очень подходит, когда нужна все информация из json'а, не работает в обратную сторону на формирования json'ов,

1.1 Обзор библиотек



По ссылкам на Да можно найти примеры использования.
* — Генерация классов для Data bind позволяет сгенерировать классы на стадии компиляции, что в теории должно давать значительный прирост производительности библиотеки,
** — Работает со static inner class имеет смысл только для случая Data bind, возможно ли сериализация и десериализация для случая статических внутренних классов (не статические внутренние классы сериализовать не рекомендуется),
*** — тоже только для случая Data bind можно ли не использовать аннотации или их использование крайне рекомендуется,

1.2 Простейшие примеры использование Data bind


Для демонстрации работы библиотек будем использовать следующий json:

jsonString =
{
  "message": "Hi",
  "place": {
    "name": "World"
  }
}

И следующие Java классы (в разных примерах могут слегка отличаться наличием аннотаций, если они обязательны):


Как можно увидеть, Java классы всего лишь состоять из двух классов Human и Place, в которых храниться сообщение Hi World!.. Json тоже содержит эти два вложенных объекта.

Примеры использования (Data bind):
Способ
FastjsonGsonLoganSquareMoshiIg json parserJacksonGenson
Инициализация---Gson gson = new Gson()---Moshi moshi = new Moshi.
Builder().build(); JsonAdapter<Human>
jsonAdapter = moshi.adapter(Human.class)
---ObjectMapper mapper = new ObjectMapper()Genson genson = new Genson()
Из Java в jsonJSON.toJSONString(human)gson.toJson(human)LoganSquare.serialize(human)jsonAdapter.toJson(human)Human__JsonHelper.serializeToJson(human)mapper.writeValueAsString(human)genson.serialize(human)
Из json в JavaJSON.parseObject(jsonString, Human.class)gson.fromJson(jsonString, Human.class)LoganSquare.parse(jsonString, Human.class)jsonAdapter.fromJson(jsonString)Human__JsonHelper.parseFromJson(jsonString)mapper.readValue(jsonString, Human.class)genson.deserialize(jsonString, Human.class)

Human__JsonHelper — это класс который Ig json parser сгенерировал на этапе компиляции, у LoganSquare так же есть генерации на этапе компиляции, но там классы подключаются "под капотом" внутри LoganSquare.

Давайте рассмотрим примеры подробнее.








Для изучения более сложных примеров библиотек см. раздел документация и генерация java классов из json. Используя генерацию можно быстро получить нужные java классы со всеми аннотациями для библиотек jackson или gson.

1.3 Простейшие примеры использование Tree Model


Использование Tree Model есть у трех библиотек: Gson, Jackson и Json Java. Давайте посмотрим их реализацию.

Для демонстрации работы библиотек будем использовать тот же json:

jsonString =
{
  "message": "Hi",
  "place": {
    "name": "World"
  }
}

Методы парсинга json'a:

ДействиеGsonJacksonJSON java
ИнициализацияJsonParser parser = new JsonParser()new ObjectMapper()-
Парсинг json'aparser.parse(<строка>)mapper.readValue(<строка>, JsonNode.class)new JSONObject(<строка>)
Получение главного объектаroot.getAsJsonObject()--
Получение строкиroot.get(<имя>).getAsString()root.get(<имя>).asText()root.getString(<имя>)
Получение дочернего объектаroot.getAsJsonObject(<имя>)root.get(<имя>)root.getJSONObject(<имя>)

Методы генерации json'a:

ДействиеGsonJacksonJSON java
Инициализация-new ObjectMapper()-
Создание главного объектаnew JsonObject()mapper.createObjectNode()new JSONObject()
Добавить строковое полеroot.addProperty(<имя>, <строка>)root.put(<имя>, <строка>)root.put(<имя>, <строка>)
Добавить дочерний объектroot.add(<имя>, <объект>);root.putObject(<имя>)root.put(<имя>, <объект>)

Примеры:

1) Чтение Gson

Чтение json с помощью Gson

2) Генерация Gson

Генерация json с помощью Gson

3) Чтение Jackson

Чтение json с помощью Jackson

4) Генерация Jackson

Генерация json с помощью Jackson

5) Чтение и генерация Json Java
И Json Java (эталонная реализация от разработчиков стандарта json), который использует JSONObject

Чтение и генерация json с помощью Json Java

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

1.4 Простейшие примеры использование Streaming API


Для демонстрации работы библиотек будем использовать все тот же json:

jsonString =
{
  "message": "Hi",
  "place": {
    "name": "World"
  }
}

Обычно Streaming API используется крайне редко, только в задачах требующих очень высокой производительности или при очень больших файлах.

Методы парсинга json'a:

ДействиеGsonJackson
Инициализация-new JsonFactory()
Парсинг json'areader = new JsonReader((<input_stream>)parser = jsonFactory.createParser(<строка>)
Проверка есть ли ещё токеныreader.hasNext()parser.hasCurrentToken()
Получение типа токенаreader.peek()parser.nextToken()
Получение следующего токенаreader.nextString()
reader.beginObject()
reader.endObject() и т.п.
parser.nextToken()
Пропуск токенаreader.skipValue()parser.nextToken()
Получение строкиreader.nextString()parser.getText()

Методы генерации json'a:

ДействиеGsonJackson
Инициализацияwriter = new JsonWriter(<output_stream>)generator = new JsonFactory().createGenerator(<output_stream>, <кодировка>)
Токен начала объектаwriter.beginObject()generator.writeStartObject()
Токен окончания объектаwriter.endObject()generator.writeEndObject()
Токен имени поляwriter.name(<имя>)generator.writeFieldName(<имя>)
Токен строкового значенияwriter.value(<строка>)generator.writeStringField(<имя>, <строка>)

Примеры:

1) Чтение в Gson

Чтение json c помощью Gson

2) Запись в Gson

Генерация json c помощью Gson

3) Чтение в Jackson

Чтение json c помощью Jackson

2) Запись в Jackson

Генерация json c помощью Jackson

1.4 Использование аналогов XPath для json


Методы:

ДействиеJsonPathFastJson
Получение значения по фильтруJsonPath.read(<json>, <шаблон>)JSONPath.eval(<java_объект>, <шаблон>)
Получение коллекции по фильтруJsonPath.read(<json>, <шаблон>)JSONPath.eval(<java_объект>, <шаблон>)

Давайте посмотрим примеры, будем использовать все тот же json

jsonString =
{
  "message": "Hi",
  "place": {
    "name": "World"
  }
}



Более сложный пример с JsonPath

2. Генерация Java классов по json схеме и валидация json


Осталось рассмотреть вопросы генерации Java классов и валидации json. Советую посмотреть следующие два online ресурса:

  1. jsonschema2pojo.org — ресурс от разработчиков библиотеки jsonschema2pojo, он позволяет из json'а или json схемы сгенерировать соответствующие классы для библиотек Jackson (первой и второй версии) и Gson со всеми аннотациями. Очень удобный ресурс для быстрого использования этих библиотек, достаточно только иметь пример json'а или json схемы.
  2. json-schema-validator.herokuapp.com — ресурс от разработчиков json-schema-validator. Он позволяет проверить json схему, сгенерировать java классы по схеме и т.д.

Давайте рассмотрим варианты использование этих библиотек в Java коде.

Пример генерации Java классов из json'а (используя jsonschema2pojo)

Пример валидации json файлов соответственно схеме (используя json-schema-validator)

Пример использования maven plugin для генерации классов по схеме json (используя jsonschema2pojo)

3. Документация


Документация всех библиотек:

JSON парсеры

  1. Alibaba Fastjson
  2. Gson
  3. LoganSquare
  4. JSON java
  5. Square Moshi
  6. Instagram Ig json parser
  7. Jackson
  8. Genson

Аналог XPath для JSON

  1. Jayway JsonPath
  2. Alibaba Fastjson

Генерация Java классов из JSON или JSON схемы и JSON валидация

  1. Jsonschema2pojo
  2. Json schema validator

Все примеры:

  1. Alibaba Fastjson
  2. Gson
  3. LoganSquare
  4. JSON java
  5. Square Moshi
  6. Instagram Ig json parser
  7. Jackson
  8. Genson
  9. Jayway JsonPath
  10. Jsonschema2pojo
  11. Json schema validator

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


Надеюсь вам понравилась эта статья, более подробную информацию о библиотеках и примерах кода можно найти на github'e. Версию на английском языке можно найтиздесь, обновляемая версия на русском будет на github'e.

Смотри также:

Комментариев нет:

Отправить комментарий