undefined

Сериализация в JSON

Java Collections
3 уровень , 3 лекция
Открыта

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

— Привет, Элли!

— Раз уж ты познакомился с 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}

Вот как все было:

В строках 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 = new 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 поля.

— Так то — 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 — имя alias. А также отметил поле weight как Ignore, в результате JSON объекта поменялся.

— Хорошо, что можно так всего настраивать – думаю, мне это обязательно пригодится.

А десериализация поймет, как с этим работать? При десериализации из JSON в Java-объект, значение поля alias будет занесено в name объекта Cat?

— Да, десериализация будет работать как надо. Она умная.

— Что не может не радовать.

Спасибо за такую интересную лекцию, Элли.

Комментарии (104)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
Дмитрий Яковенко 35 уровень, Москва
7 мая 2021
Написал статью - "Подключение библиотек с помощью Maven", может кому пригодится.
B14CK70P 35 уровень
15 апреля 2021
Инструкции по добавлению фрейма написали люди ниже. От себя добавлю запутавшимся, что сработало или нет проверяется появлением возможности импорта класса.
мистер т 35 уровень, Москва
10 апреля 2021
По ссылке -> 1. Jackson Databind -> 2.12.2 (или свежее) -> качаем Files - bundle (1.4 MB); В идее File -> project structure -> Project Settings - Librares -> наверху + Java - выбираем то что скачали.
Maximysss 24 уровень, Минск
3 апреля 2021
Помучался с установкой...Короче -на сайте где файл -чтоб скачать нажимайте -bundle Потом еще совет- после того как все загрузили File-->File structure-->Libriries-->+-->java--> выбирайте 3 файла именно с версией 2.6.1 Удачи!
Вадим Илларионович 42 уровень, Харьков
23 марта 2021
Для начала тебе надо скачать этот фреймворк и добавить его себе в проект. Делать это надо в Intellij IDEA само собой. Загрузить фрейморк можно по ссылке. ?????? какой именно ???? 1. Jackson Databind? 2. Jackson Core?? 3. Jackson Annotations? я так понимаю второй?
Georgy 36 уровень, Москва
5 февраля 2021
Нужно добавить только одну библиотеку в Maven com.fasterxml.jackson.core:jackson-databind , она содержит в себе все 3 составляющие: core, anotation и bind. File -> Project Settings -> Libraries -> + -> form Maven... -> -> com.fasterxml.jackson.core:jackson-databind -> -> выбираем последнюю версию (на момент комментария 2.12.1) -> -> выбираем JavaCollections -> Кайфуем ^^
Эли Гутман 37 уровень
1 января 2021
{"age":5, "alias":"Murka"} И как age оказался перед alias, если в самом классе другой порядок?
Иван 41 уровень, Краснодар
28 декабря 2020
Как скачать эти первые 3 файла на сайте, не могу понять?
Raphael 41 уровень, Москва
1 декабря 2020
Элли : "Код остался тот же, но я поменялА аннотации: указаЛ другое имя полю name — имя alias. А также отметиЛ ..." ... ... Спасибо за такую интересную лекцию... Элли ) ... или Эль ? ) ... Эль-Мачо )
Уася 41 уровень, Замусральск Expert
25 ноября 2020
Для тех, кто юзает эклипс: по ссылке скачиваете Jackson Databind, Jackson Annotations и Jackson Core -> правой кнопкой мыши по проекту-> Properties-> Java Build Path-> Libraries-> Add External JARs Могли бы в статье и такой вариант описать. Или символы для текста нынче сильно дорогие?