— Привіт, Аміго!

— Привіт, Еллі!

— Якщо ти познайомився з JSON, давай поговоримо про нього сьогодні докладніше.

— Ок. А де він зазвичай використовується?

— Зазвичай, справа виглядає так. Хтось (клієнт) запитує Java-програми (сервера) дані. Програма створює Java-об'єкти та заповнює їх інформацією з бази даних. Потім перетворює їх у формат зрозумілий запитувачу (клієнту), наприклад JSON, і відсилає їх назад.

Давай я тобі розповім, як працювати з ним із Java. Власне, нам знадобляться лише дві речі – серіалізувати Java-об'єкти у JSON-формат та десеріалізувати Java-об'єкти з формату JSON.

Тобто. JSON – це стандарт транспортування повідомлень/даних від однієї програми до іншої. Таких стандартів досить багато. Але якщо програму написано на JavaScript, вона зазвичай намагається працювати з JSON.

— Ок. Я готовий.

— Чудово. Тоді почнемо.

Серіалізація в JSON - 1

Як ти вже знаєш, Java має вбудовані стандартні засоби серіалізації. Але JSON до них не належать. Тому якщо тобі треба використовувати серіалізацію об'єкта в JSON, ти можеш використовувати один із популярних фреймворків(бібліотек), які це вміють.

— А чим відрізняються різні фреймворки?

— Зазвичай вони відрізняються ступенем складності: є фреймворки, які вміють робити тільки найнеобхідніше, але дуже маленькі і прості. А є й великі складні фреймворки, які можуть робити набагато більше.

Одним із популярних фреймворків вважається Jackson. Ми розглянемо роботу з JSON на його прикладі.

Для початку тобі треба завантажити цей фреймворк та додати його собі до проекту. Робити це треба в Intellij IDEA само собою. Завантажити фреймворк можна за посиланням.

— Готово.

— Чудово. Тоді продовжимо.

Конвертувати Java-об'єкт у JSON приблизно так само просто, як і серіалізувати його. Для цього є спеціальний клас ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper).

Давай я покажу тобі робочий приклад, а потім ми його розберемо:

Конвертація об'єкта в JSON
public static void main(String[] args) throws IOException
{
 //Створення об'єкта для серіалізації в JSON
 Cat cat = new Cat();
 cat.name = "Murka";
 cat.age = 5;
 cat.weight = 4;

 //писати результат серіалізації будемо у Writer(StringWriter)
 StringWriter writer = new StringWriter();

 // це об'єкт Jackson, який виконує серіалізацію
 ObjectMapper mapper = new ObjectMapper();

 // сама серіалізація: 1-куди, 2-що
 mapper.writeValue(writer, cat);

 //Перетворюємо все записане в StringWriter на рядок
 String result = writer.toString();
 System.out.println(result);
}
Клас Cat, об'єкт якого конвертує в JSON
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;
Cat(){}
}
Результат серіалізації та виведення на екран:
{"name":"Murka", "age":5, "weight":4}< /code>

Ось як усе було:

У рядках 4-7 ми створюємо об'єкт класу Cat і заповнюємо його даними.

Рядок 10 – створюємо об'єкт Writer, куди писатимемо рядок — JSON представлення об'єкта.

Рядок 13 – створюємо об'єкт ObjectMapper, який і виконує всю серіалізацію.

Рядок 16 – пишемо JSON-подання об'єкта cat в writer.

Рядки 19-20 – виводимо результат на екран.

Все виглядає досить просто. Не складніше за рідну серіалізацію в Java.

— А як виглядатиме десеріалізація?

— Та майже так само, лише коротше:

Конвертація об'єкта з JSON
public static void main(String[] args) throws IOException
{
 String jsonString = "{ \"name\":\"Murka\", \"age\":5, \"weight\":4}";
 StringReader reader = новий StringReader(jsonString);

 ObjectMapper mapper = new ObjectMapper();

 Cat cat = mapper.readValue(reader , Cat.class);
}
Клас, об'єкт якого десеріалізується з JSON-формату
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;

 Cat() { }
}

Тут ще простіше. Беремо ObjectMapper і передаємо в нього рядок з JSON або StringReader, а також клас об'єкта, який треба десеріалізувати. Викликаємо метод readValue, і на виході отримуємо готовий Java-об'єкт з усіма даними.

— Ну, як десеріалізація в Java.

— Майже. До об'єктів, які серіалізуються/десеріалізуються в JSON, є кілька вимог:

1) поля мають бути видимі: або public або мати getter'и та setter'и;

2) має бути конструктор за замовчуванням (без параметрів).

— Зрозуміло. Очікувано, загалом. Хоча Java чудово серіалізувала і private поля.

— Так то # 8212; Java. Вона має доступ до прихованих даних. Від себе не приховуєш.

Тут є ще третій аспект. Сподіваюся, ти звернув увагу на інструкцію @JsonAutoDetect у класі Cat?

— Ага. Саме хотів запитати – що це таке.

— Це інструкції – службова інформація для фреймворку Jackson. Можна дуже гнучко керувати результатом серіалізації в форматі JSON, розставляючи правильні анотації.

— Круто! А що за інструкції є?

— Ось тобі кілька:

Аннотація Опис
@JsonAutoDetect Ставиться перед класом.
Позначає клас як готовий до серіалізації в JSON.
@JsonIgnore Ставиться перед властивістю.
Властивість ігнорується під час серіалізації.
@JsonProperty Ставиться перед властивістю або getter'ом або setter'ом. Дозволяє встановити інше ім'я поля під час серіалізації.
@JsonPropertyOrder Ставиться перед класом.
Дозволяє встановити порядок полів для серіалізації.

— Як цікаво. А ще є?

— Є багато. Але не зараз. Зараз давай трохи переробимо наш перший приклад:

Конвертація об'єкта в JSON
public static void main(String[] args) throws IOException
{
 Cat cat = new Cat();
 cat.name = "Murka";
 cat.age = 5;
 cat.weight = 4;

 StringWriter writer = new StringWriter();

 ObjectMapper mapper = new ObjectMapper();

 mapper.writeValue(writer, cat) ;

 String result = writer.toString();
 System.out.println(result);
}
Клас, об'єкт якого конвертує в JSON
@JsonAutoDetect
class Cat
{
 @JsonProperty("alias")
 public String name;
 public int age;
 @JsonIgnore
 public int weight;

 Cat() {
 }
}
Результат серіалізації та виведення на екран:
{"age":5, "alias":"Murka"}

Код залишився той самий, але я змінила інструкції: вказала інше ім'я поля name — ім'я або. А також відзначила поле weight як Ignore, в результаті JSON об'єкта помінявся.

— Добре, що можна так налаштовувати – думаю, мені це обов'язково знадобиться.

А десеріалізація зрозуміє, як із цим працювати? При десеріалізації з JSON в Java-об'єкт значення поля alias буде занесено в name об'єкта Cat?

— Так, десеріалізація працюватиме як слід. Вона розумна.

— Що не може не тішити.

Дякую за таку цікаву лекцію, Еллі.