Шпаргалка Java програміста 8. Бібліотеки для роботи з Json (Gson, Fastjson, LoganSquare, Jackson, JsonPath та інші)

image
В одній з моїх минулих статей я розповідав про своє opensorce pet проекті useful-java-links, ідея якого зібрати якомога більше посилань на корисні Java бібліотеки і фреймворки. У нього так само є підпроект Hello World project ідея якого для кожної бібліотеки зібрати кілька простих прикладів її використання.
Проблема програмістів Java світі в тому що крім стандартної бібліотеки JDK є величезна інших корисних бібліотек, причому перехід від однієї бібліотеки до іншої може викликати проблеми з-за неповної документації, відсутність простих прикладів або навіть складності зрозуміти які залежно потрібно додати в maven щоб все запустилося. А на новій роботі цілком можуть використовувати замість твоєї улюбленої бібліотеки ту яку ти не знаєш. Ідея проекту полегшити вивчення і вибір різних бібліотек.
Загальний зміст 'Шпаргалок'1. JPA і Hibernate в питаннях і відповідях
2. Триста п'ятдесят найпопулярніших не мобільних Java opensource проектів на github
3. Колекції в Java (стандартні, guava, apache, скарб, gs-collections та інші)
4. Java Stream API
5. Двісті п'ятдесят російськомовних навчальних відео доповідей і лекцій про Java
6. Список корисних посилань для Java програміста
7 Типові завдання
  7.1 Оптимальний шлях перетворення InputStream в рядок
  7.2 найпродуктивніший спосіб обходу Map'и, підрахунок кількості входжень підрядка
8. Бібліотеки для роботи з Json (Gson, Fastjson, LoganSquare, Jackson, JsonPath та інші)
Отже, давайте подивимося які відомі бібліотеки для роботи з JSON в Java…
Цитата useful-java-links:
8. Робота з Json...8. Робота з Json
JSON парсери
  1. Alibaba Fastjson Швидкий JSON обробник, рейтинг github'а — 4851. User guide і Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
  2. Gson — Проста серіалізації об'єктів в JSON і назад. Хороша продуктивність і легкість у використанні, рейтинг github'а — 4120. User guide і Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
  3. LoganSquare -Бібліотека парсинга і серіалізації JSON, заснована на jackson's streaming API. За словами розробників, перевершує по продуктивності GSON і Jackson бібліотеки, рейтинг github'а — 2188. User guide і Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
  4. JSON java Реалізація роботи з JSON в Java від розробників JSON стандарту, рейтинг github'а — 1937. User guide і Hello World examples. Ліцензія: Crockford's license (MIT License + "Good, not Evil".
  5. Square Moshi JSON бібліотека для Android і Java, служить для спрощення парсинга Json в об'єкти Java, рейтинг github'а — 1732. User guide і Hello World examples. Ліцензія: Apache 2 Ліцензія сумісна з закритим
  6. Instagram Ig json parser Швидкий JSON парсер для java проектів, рейтинг github'а — 921. User guide і Hello World examples. Ліцензія: BSD 3. Ліцензія сумісна з закритим
  7. Jackson — Схоже на GSON, але більш продуктивна, якщо вам треба часто створювати екземпляр бібліотеки. Підпроекти: Jackson core Базова частина функціоналу, Jackson databind Базова реалізація databind'а, рейтинг github'а — 881. User guide і Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
  8. Genson — Потужна і проста у використанні Java бібліотека для перетворення/з JSON, рейтинг github'а — 108. User guide і Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
Аналог XPath для JSON
  1. Jayway JsonPath Java JsonPath — реалізація аналога XPATH тільки для Json, а не XML, рейтинг github'а — 849. User guide і Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
  2. Alibaba Fastjson Швидкий JSON обробник, рейтинг github'а — 4851. User guide і Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
Генерація Java класів з JSON або JSON схеми і JSON валідація
  1. Jsonschema2pojo Генерація Java класів з JSON схеми (або прикладу JSON) з анотаціями для data binding для Jackson 1.x or 2.x, Gson і т. п.., рейтинг github'а — 1664. User guide, Hello World examples. Ліцензія: Apache 2. Ліцензія сумісна з закритим
  2. Json schema validator Валідація JSON схеми, реалізована на чистої Java, створена з метою перевірки Json файлів, використовуючи Json схеми., так само може генерувати Java класи зі схеми і навпаки, рейтинг github'а — 547. User guide, Hello World examples. Ліцензія: GNU Lesser 3/Apache 2. Ліцензія сумісна з закритим

Отже, у нас вісім бібліотек для серіалізації та десеріалізації в 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 Огляд бібліотек









Спосіб Fastjson Gson LoganSquare JSON java Moshi Ig json parser Jackson Genson JsonPath 1. Data bind Так Так Да - Да Да Да Да - 2. Tree Model - Так - Да - - Да - - 3. Streaming API - Так - - - - Да - - 4. Аналоги XPath Да - - - - - - - Да 5. Генерація класів для Data bind* - - Да - - Да - - - 6. Github's star 4851 4120 2188 1937 1732 921 881 108 849 7. Працює з static inner class** Да Так Нет - Да Нет Да Да - 8. Обов'язковість анотацій*** Нет Нет Да - Нет Да Нет Нет -
За посиланнями на Так можна знайти приклади використання.
*
— Генерація класів для Data bind дозволяє згенерувати класи на стадії компіляції, що в теорії має давати значний приріст продуктивності бібліотеки,
**
— Працює з static inner class має сенс тільки для випадку Data bind, можливо сериализация і десериализация для випадку внутрішніх статичних класів (не статичні внутрішні класи сериализации не рекомендується),
***
— теж тільки для випадку Data bind можна не використовувати анотації або їх використання вкрай рекомендується,
1.2 Найпростіші приклади використання Data bind
Для демонстрації роботи бібліотек будемо використовувати наступний json:
jsonString =
{
"message": "Ні",
"place": {
"name": "World"
}
}

І наступні класи Java (в різних прикладах можуть злегка відрізнятися наявністю анотацій, якщо вони обов'язкові):
класи Java
class Human {
private String message;
Place private place;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public Place getPlace() {
return place;
}

public void setPlace(Place place) {
this.place = place;
}

public void say() {
System.out.println();
System.out.println(getMessage() + " , " + getPlace().getName() + "!");
}
}

class Place {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

// init class
Place place = new Place();
place.setName("World");

Human human = new Human();
human.setMessage("Ні");
human.setPlace(place);

Як можна побачити, Java класи всього лише складатися з двох класів Human і Place, у яких зберігатися повідомлення Hi World!.. Json теж містить ці два вкладених об'єкта.






Приклади використання (Data bind):
Спосіб
Fastjson Gson LoganSquare Moshi Ig json parser Jackson Genson Ініціалізація ---
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 в json
JSON.toJSONString(human)
gson.toJson(human)
LoganSquare.serialize(human)
jsonAdapter.toJson(human)
Human__JsonHelper.serializeToJson(human)
mapper.writeValueAsString(human)
genson.serialize(human)
З json в Java
JSON.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.
Давайте розглянемо приклади докладніше.
Fastjson
// convert to json
String jsonString = JSON.toJSONString(human);
System.out.println("json " + jsonString); // надрукує "json {"message":"Ні","place":{"name":"World"}}"

// convert from json
Human newHuman = JSON.parseObject(jsonString, Human.class);
newHuman.say(); // надрукує "Hi , World!"

Докладний приклад
Gson
// convert to json
Gson gson = new Gson();
String jsonString = gson.toJson(human);
System.out.println("json " + jsonString); // надрукує "json {"message":"Ні","place":{"name":"World"}}"

// convert from json
Human newHuman = gson.fromJson(jsonString, Human.class);
newHuman.say(); // надрукує "Hi , World!"

Докладний приклад
LoganSquare
@JsonObject
public class Human {
@JsonField(name="message")
public String message;
@JsonField(name="place")
public Place place;

....

// convert to json
String jsonString = LoganSquare.serialize(human);
System.out.println("json " + jsonString); // надрукує "json {"place":{"name":"World"},"message":"Ні"}"

// convert from json
Human newHuman = LoganSquare.parse(jsonString, Human.class);
newHuman.say(); // надрукує "Hi , World!"

Докладний приклад
Moshi
// convert to json
Moshi moshi = new Moshi.Builder().build();
JsonAdapter<Human> jsonAdapter = moshi.adapter(Human.class);

String jsonString = jsonAdapter.toJson(human);
System.out.println("json " + jsonString); // надрукує "json {"message":"Ні","place":{"name":"World"}}"

// convert from json
Human newHuman = jsonAdapter.fromJson(jsonString);
newHuman.say(); // надрукує "Hi , World!"

Докладний приклад
Ig json parser
@JsonType
public class Human {
@JsonField(fieldName="message")
public String message;
@JsonField(fieldName="place")
public Place place;

...

// convert to json
String jsonString = Human__JsonHelper.serializeToJson(human);
System.out.println("json " + jsonString); // надрукує "json {"place":{"name":"World"},"message":"Ні"}"

// convert from json
Human newHuman = Human__JsonHelper.parseFromJson(jsonString);
newHuman.say(); // надрукує "Hi , World!"

Докладний приклад
Jackson
// convert to json
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(human);
System.out.println("json " + jsonString); // надрукує "json {"message":"Ні","place":{"name":"World"}}"

// convert from json
Human newHuman = mapper.readValue(jsonString, Human.class);
newHuman.say(); // надрукує "Hi , World!"

Докладний приклад
Genson
// convert to json
String jsonString = new Genson().serialize(human);

System.out.println("json " + jsonString); // надрукує "json {"message":"Ні","place":{"name":"World"}}"

// convert from json
Human newHuman = new Genson().deserialize(jsonString, Human.class);
newHuman.say(); // надрукує "Hi , World!"

Докладний приклад
Для вивчення більш складних прикладів бібліотек див. розділ документація і генерація java класів з json. Використовуючи генерацію можна швидко отримати потрібні java класи з усіма анотаціями для бібліотек jackson або gson.
1.3 Найпростіші приклади використання Tree Model
Використання Tree Model є у трьох бібліотек: Gson, Jackson і Json Java. Давайте подивимося їх реалізацію.
Для демонстрації роботи бібліотек будемо використовувати той же json:
jsonString =
{
"message": "Ні",
"place": {
"name": "World"
}
}

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






Дія Gson Jackson JSON java Ініціалізація
JsonParser parser = new JsonParser()
new ObjectMapper()
- Парсинг json'a
parser.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:






Дія Gson Jackson JSON 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
JsonParser parser = new JsonParser();
JsonElement jsonElement = parser.parse("{\"message\":\"Hi\",\"place\":{\"name\":\"World!\"}}");

JsonObject rootObject = jsonElement.getAsJsonObject(); // читання головного об'єкта
String message = rootObject.get("message").getAsString(); // отримати полі "message" як рядок
JsonObject childObject = rootObject.getAsJsonObject("place"); // отримати об'єкт Place 
String place = childObject.get("name").getAsString(); // отримати полі "name"
System.out.println(message + " " + place); // надрукує "Hi World!"*/

Докладний приклад
2) Генерація Gson
Генерація json з допомогою Gson
JsonObject rootObject = new JsonObject(); // створюємо головний об'єкт
rootObject.addProperty("message", "Ні"); // записуємо текст в полі "message"
JsonObject childObject = new JsonObject(); // створюємо об'єкт Place
childObject.addProperty("name", "World!"); // записуємо текст в полі "name" у об'єкт Place
rootObject.add("place", childObject); // зберігаємо дочірній об'єкт у полі "place"

Gson gson = new Gson();
String json = gson.toJson(rootObject); // генерація json рядка
System.out.println(json); // надрукує "{"message":"Hi","place":{"name":"World!"}}"

Докладний приклад
3) Читання Jackson
Читання json з допомогою Jackson
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readValue("{\"message\":\"Hi\",\"place\":{\"name\":\"World!\"}}", JsonNode.class); // парсинг тексту
String message = rootNode.get("message").asText(); // отримання рядки з поля "message"
JsonNode childNode = rootNode.get("place"); // отримуємо об'єкт Place
String place = childNode.get("name").asText(); // отримуємо рядок з поля "name"
System.out.println(message + " " + place); // надрукує "Hi World!"

Докладний приклад
4) Генерація Jackson
Генерація json з допомогою Jackson
OutputStream outputStream = new ByteArrayOutputStream();

ObjectMapper mapper = new ObjectMapper();
ObjectNode rootNode = mapper.createObjectNode(); // створення головного об'єкта
rootNode.put("message", "Ні");
ObjectNode childNode = rootNode.putObject("place"); // створення дочірнього об'єкта Place
childNode.put("name", "World!");
mapper.writeValue(outputStream, childNode); // запис json рядка в стрім

System.out.println(outputStream.toString()); // надрукує "{"message":"Hi","place":{"name":"World!"}}"

Докладний приклад
5) Читання і генерація Json Java
І Json Java (еталонна реалізація від розробників стандарту json), який використовує JSONObject
Читання і генерація json з допомогою Json Java
// convert to Java json
JSONObject root = new JSONObject(); // створюємо головний об'єкт
root.put("message", "Ні");
JSONObject place = new JSONObject(); // створюємо об'єкт Place
place.put("name", "World!");
root.put("place", place); // зберігаємо об'єкт Place в поле place
String json = root.toString();
System.out.println(json); // надрукує "{"message":"Hi","place":{"name":"World!"}}"

System.out.println();
// convert json to Java
JSONObject jsonObject = new JSONObject(json); // парсинг json
String message = jsonObject.getString("message");
String name = jsonObject.getJSONObject("place").getString("name");
System.out.println(message + " " + name); // надрукує "Hi World!"

Докладний приклад
загалом, можна помітити, що у всіх бібліотеках виконуються приблизно ті ж дії, відрізняються тільки назви класів.
1.4 Найпростіші приклади використання Streaming API
Для демонстрації роботи бібліотек будемо використовувати все той же json:
jsonString =
{
"message": "Ні",
"place": {
"name": "World"
}
}

Зазвичай Streaming API використовується вкрай рідко, тільки в завданнях, що вимагають дуже високої продуктивності або при дуже великих файлів.
Методи парсинга json'a:









Дія Gson Jackson Ініціалізація -
new JsonFactory()
Парсинг json'a
reader = 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:







Дія Gson Jackson Ініціалізація 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
String str = "{\"message\":\"Hi\",\"place\":{\"name\":\"World!\"}}";
InputStream in = new ByteArrayInputStream(str.getBytes(Charset.forName("UTF-8")));
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
while (reader.hasNext()) { // обходимо всі токени
JsonToken jsonToken = reader.peek(); // отримуємо наступного тип токена
if(jsonToken == JsonToken.BEGIN_OBJECT) { // якщо початок об'єкта
reader.beginObject();
} else if(jsonToken == JsonToken.END_OBJECT) { // якщо кінець об'єкта
reader.endObject();
} if(jsonToken == JsonToken.STRING) { // у разі якщо токен рядковий знання - виводимо на екран 
System.out.print(reader.nextString() + " "); // надрукує Hi World!
} else {
reader.skipValue(); // пропускаємо всі інші токени
}
}
reader.close();

Докладний приклад
2) Запис у Gson
Генерація json c допомогою Gson
OutputStream outputStream = new ByteArrayOutputStream();
JsonWriter writer = new JsonWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.beginObject(); // створюємо токен початку головного об'єкта
writer.name("message"); // записуємо поле message
writer.value("Ні");
writer.name("place"); // зберігаємо об'єкт Place в поле place
writer.beginObject(); // починаємо об'єкт Place
writer.name("name");
writer.value("World!");
writer.endObject(); // закриваємо об'єкт Place
writer.endObject(); // закриваємо головний об'єкт
writer.close();
System.out.println(outputStream.toString()); // надрукує "{"message":"Hi","place":{"name":"World!"}}"

Докладний приклад
3) Читання в Jackson
Читання json c допомогою Jackson
JsonFactory jsonFactory = new JsonFactory();
JsonParser jsonParser = jsonFactory.createParser("{\"message\":\"Hi\",\"place\":{\"name\":\"World!\"}}");
JsonToken jsonToken = jsonParser.nextToken();
while(jsonParser.hasCurrentToken()) { // обходимо токени
if(jsonToken == VALUE_STRING) { // у разі якщо токен рядковий знання - виводимо на екран 
System.out.print(jsonParser.getText() + " "); // надрукує "Hi World!"
}
jsonToken = jsonParser.nextToken();
}

Докладний приклад
2) Запис у Jackson
Генерація json c допомогою Jackson
JsonFactory jsonFactory = new JsonFactory();
OutputStream outputStream = new ByteArrayOutputStream();
JsonGenerator jsonGenerator = jsonFactory.createGenerator(outputStream, JsonEncoding.UTF8); 
jsonGenerator.writeStartObject(); // створюємо токен початку головного об'єкта
jsonGenerator.writeStringField("message", "Ні"); // створюємо поле message
jsonGenerator.writeFieldName("place");
jsonGenerator.writeStartObject(); // починаємо об'єкт Place
jsonGenerator.writeStringField("name", "World!");
jsonGenerator.writeEndObject(); // закриваємо об'єкт Place
jsonGenerator.writeEndObject(); // закриваємо головний об'єкт
jsonGenerator.close();
System.out.println(outputStream.toString()); // надрукує "{"message":"Hi","place":{"name":"World!"}}"

Докладний приклад
1.4 Використання аналогів XPath для json
Методи:



Дія JsonPath FastJson Отримання значення по фільтру
JsonPath.read(<json> <шаблон>)
JSONPath.eval(<java_объект> <шаблон>)
Отримання колекції по фільтру
JsonPath.read(<json> <шаблон>)
JSONPath.eval(<java_объект> <шаблон>)
Давайте подивимося приклади, будемо використовувати все той же json
jsonString =
{
"message": "Ні",
"place": {
"name": "World"
}
}

C допомогою JsonPath
String jsonHiWorld = "{\"message\":\"Hi\",\"place\":{\"name\":\"World!\"}}\"";

String message = JsonPath.read(jsonHiWorld, "$.message");
String place = JsonPath.read(jsonHiWorld, "$.place.name");
System.out.println(message + " " + place); // надрукує "Hi World!"

Докладний приклад
C допомогою FastJson
// перетворення з json'a в Java об'єкти
String jsonString = "{\"message\":\"Hi\",\"place\":{\"name\":\"World!\"}}\"";
Human newHuman = JSON.parseObject(jsonString, Human.class);

// пошук інформації в Java об'єкти використовуючи eval
Object message = JSONPath.eval(newHuman, "$.message");
Object world = JSONPath.eval(newHuman, "$.place.name");
System.out.println(message + " " + world); // print Hi World

Докладний приклад
Більш складний приклад з JsonPath
List < String> authors = JsonPath.read(json, "$.store.book[*].author");
System.out.println("authors: " + authors); // print ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]

List<Map<String, Object>> expensiveBooks = JsonPath
.using(Configuration.defaultConfiguration())
.parse(json)
.read("$.store.book[?(@.price > 22)].title", List.class);

System.out.println(expensiveBooks); // print ["Hello, Middle-earth! "] 

де json це
json =
String json = "{\n" +
" \"store\": {\n" +
" \"book\": [\n" +
" {\n" +
" \"category\": \"reference\",\n" +
" \"author\": \"Nigel Rees\",\n" +
" \"title\": \"Sayings of the Century\",\n" +
" \"price\": 8.95\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"Evelyn Waugh\",\n" +
" \"title\": \"Sword of Honour\",\n" +
" \"price\": 12.99\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"Herman Melville\",\n" +
" \"title\": \"Moby Dick\",\n" +
" \"isbn\": \"0-553-21311-3\",\n" +
" \"price\": 8.99\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"J. R. R. Tolkien\",\n" +
" \"title\": \"Hello, Middle-earth! \",\n" +
" \"isbn\": \"0-395-19395-8\",\n" +
" \"price\": 22.99\n" +
" }\n" +
" ],\n" +
" \"bicycle\": {\n" +
" \"color\": \"red\",\n" +
" \"price\": 19.95\n" +
" }\n" +
" },\n" +
" \"expensive\": 10\n" +
"}";

Докладний приклад
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)
// Init json
String source = "{\n" +
" \"type\":\"object\",\n" +
" \"properties\": {\n" +
" \"messageHiWorld\": {\n" +
" \"type\": \"string\"\n" +
" },\n" +
" \"bar\": {\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"baz\": {\n" +
" \"type\": \"boolean\"\n" +
" }\n" +
" }\n" +
"}";

// Init config
JCodeModel codeModel = new JCodeModel();

GenerationConfig config = new DefaultGenerationConfig() {
@Override
public boolean isGenerateBuilders() { // set config option by overriding method
return true;
}
};

// Generate Java POJO from json
SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(), new SchemaStore()), new SchemaGenerator());
mapper.generate(codeModel, "HelloWorldClass", "com.github.vedenin", source);

// Save generated class to file
File directory = new File("helloworlds/3.8-json/jsonschema2pojo/output");
directory.mkdirs();
codeModel.build(directory);

// Show generated class
File cls = new File("helloworlds/3.8-json/jsonschema2pojo/output/com/github/vedenin/HelloWorldClass.java");
String codeHelloWorld = Files.toString(cls, Charsets.UTF_8);
System.out.println(codeHelloWorld);

Докладний приклад
Приклад валідації json файлів відповідно схемою (використовуючи json-schema-validator)
final JsonNode fstabSchema = Utils.loadResource("/fstab.json");
final JsonNode good = Utils.loadResource("/fstab-good.json");
final JsonNode bad = Utils.loadResource("/fstab-bad.json");
final JsonNode bad2 = Utils.loadResource("/fstab-bad2.json");

final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();

final JsonSchema schema = factory.getJsonSchema(fstabSchema);

ProcessingReport report;

report = schema.validate(good);
System.out.println(report);

report = schema.validate(bad);
System.out.println(report);

report = schema.validate(bad2);
System.out.println(report);

Докладний приклад
Приклад використання maven plugin для генерації класів за схемою json (використовуючи jsonschema2pojo)1) В maven додаємо наступний код, змінюючи sourceDirectory (де лежать схеми json) і targetPackage (пакет у згенерованих класів)
<build>
<plugins>
<plugin>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>0.4.22</version>
<configuration>
``${basedir}/src/main/resources</sourceDirectory>
<targetPackage>com.github.vedenin</targetPackage>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

2) Покласти потрібні схеми json в sourceDirectory
3) Після запуску install maven'a за всіма схемами будуть згенеровані Java класи.
Докладний приклад
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.
Допомога проекту:
Буду вдячний за додавання нових корисних посилань в список бібліотек, так за додавання Hello world прикладів, і за виправлення російської та англійської граматики у статтях (див. докладніше тут). Буду вдячний за будь-які зауваження і додавання.
Загальний зміст 'Шпаргалок'1. JPA і Hibernate в питаннях і відповідях
2. Триста п'ятдесят найпопулярніших не мобільних Java opensource проектів на github
3. Колекції в Java (стандартні, guava, apache, скарб, gs-collections та інші)
4. Java Stream API
5. Двісті п'ятдесят російськомовних навчальних відео доповідей і лекцій про Java
6. Список корисних посилань для Java програміста
7 Типові завдання
  7.1 Оптимальний шлях перетворення InputStream в рядок
  7.2 найпродуктивніший спосіб обходу Map'и, підрахунок кількості входжень підрядка
8. Бібліотеки для роботи з Json (Gson, Fastjson, LoganSquare, Jackson, JsonPath та інші)

Наступну статтю мені хотілося б по темі...

/>
/>


<input type=«checkbox» id=«vv72995»
class=«checkbox js-field-data»
name=«variant[]»
value=«72995» />
Bean Mapping
<input type=«checkbox» id=«vv72997»
class=«checkbox js-field-data»
name=«variant[]»
value=«72997» />
Functional Programming
<input type=«checkbox» id=«vv72999»
class=«checkbox js-field-data»
name=«variant[]»
value=«72999» />
Reactive Programming
<input type=«checkbox» id=«vv73001»
class=«checkbox js-field-data»
name=«variant[]»
value=«73001» />
Code generation and changing byte code
<input type=«checkbox» id=«vv73003»
class=«checkbox js-field-data»
name=«variant[]»
value=«73003» />
Machine Learning
<input type=«checkbox» id=«vv73005»
class=«checkbox js-field-data»
name=«variant[]»
value=«73005» />
Natural Language Processing (NLP)
<input type=«checkbox» id=«vv73007»
class=«checkbox js-field-data»
name=«variant[]»
value=«73007» />
Іншу тему (в коментарях)
<input type=«checkbox» id=«vv73009»
class=«checkbox js-field-data»
name=«variant[]»
value=«73009» />
Не має значення
<input type=«checkbox» id=«vv73011»
class=«checkbox js-field-data»
name=«variant[]»
value=«73011» />
Все погано, не потрібно більше статей

Проголосувало 24 людини. Утрималося 9 осіб.


Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.


Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.