Преобразование объектов Java (POJO) В JSON и из него с помощью Gson
В этом уроке мы рассмотрим примеры того, как преобразовать объект Java (POJO) в JSON и как преобразовать JSON в объект Java с помощью Gson.
- Автор записи
Вступление
Формат JSON-один из самых популярных способов сериализации данных. Знание того, как читать и писать, является важным навыком для любого программиста. Существует несколько библиотек Java, которые могут анализировать JSON, но в этом уроке мы сосредоточимся на проекте с открытым исходным кодом, разработанном Google, под названием GSON.
GSON – это облегченная библиотека Java, которая обеспечивает функциональность сериализации/десериализации. Что отличает GSON , так это его поддержка Универсальных типов , которая ограничена некоторыми, но не всеми альтернативными библиотеками.
Примечание: Если вы не знакомы с дженериками и почему это так важно – не стесняйтесь прочитать наше Руководство по пониманию дженериков Java .
Поскольку мы работаем с внешней библиотекой, давайте добавим зависимость. Если вы используете Maven, вы можете добавить его с помощью:
Или, если вы используете Gradle, вы можете добавить:
Создание пользовательского класса
Давайте создадим пользовательский класс, который мы сначала сериализуем в JSON и в который мы десериализуем из JSON – Студент :
Для нашего Студента у нас дополнительно есть перечисление , представляющее, находятся ли они в бюджете ( СУБСИДИРУЮТСЯ ) или нет ( НЕСУБСИДИРОВАННЫЕ ):
Преобразуйте объект Java в объект JSON с помощью GSON
Теперь, когда мы определили наш класс, давайте создадим его экземпляр и сериализуем его в эквивалентное представление JSON. Мы сделаем это с помощью метода toJSON () , который принимает объект в качестве аргумента и возвращает представление этого объекта в формате JSON:
Это преобразует наши POJO в строки JSON, которые при печати приводят к:
Преобразование строки JSON в объект Java
Чтобы обратить этот процесс вспять и сопоставить объект JSON с POJO, мы будем использовать метод FromJSON () . Он принимает строку JSON или a Считыватель и класс или/| Введите токен .
Давайте сначала взглянем на первое:
Это создает экземпляр и заполняет объект max данными из объекта JSON:
Преобразование файла JSON в объект Java
Теперь мы, возможно, не будем работать с JSON в строковом формате – нам часто приходится читать файлы JSON . Метод FromJSON() принимает экземпляр Reader , который мы также можем использовать для предоставления данных JSON.
Давайте переместим данные Эми в файл amy.json :
Теперь мы можем использовать Reader , например FileReader , чтобы прочитать этот файл и использовать его для ввода вместо строки. Кроме того, вместо использования Student.class , мы предоставляем Тип . Этот Тип извлекается из Gson TypeToken , что во многом аналогично ссылке Джексона На тип :
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Это, безусловно, также создает экземпляры и заполняет наш Студент POJO:
Компактная и красивая печать
По умолчанию GSON печатает JSON в компактном формате, который мы могли видеть ранее:
Между именами полей и их значениями, полями объектов и объектами в массивах нет пробелов. Кроме того, нет ни одной новой строки . Если скопировать в виде строки – \n (новые строки) будут присутствовать, однако, это компактное представление является проблемой для чтения.
Мы можем довольно легко включить красивую печать с помощью Gson. При создании экземпляра Gson вместо вызова пустого конструктора по умолчанию – мы можем использовать конструктор GsonBuilder() :
Теперь мы можем использовать экземпляр gson почти так же, как и раньше:
Хотя, на этот раз, при печати – строка JSON довольно-печать включена включена :
Присвоение имен полям JSON с помощью @SerializedName
Сериализация обычно используется для передачи данных между службами – в первую очередь, через API REST. При работе с различными службами, командами или даже языками, которые обрабатывают предоставляемые нами данные, мы можем захотеть изменить сериализованные имена определенных полей в соответствии с более широко принятыми стандартами или стандартами определенной службы, которая будет обрабатывать предоставляемые нами данные.
Например, мы можем предоставлять данные JSON из службы Java в службу Python. Соглашения об именах Java следуют camelCase , в то время как соглашения об именах Python следуют нижним регистром_высокие баллы для неконстант и классов.
Зная, что мы будем предоставлять наши данные службе или лицу, которые могут захотеть использовать другие соглашения, мы можем изменить сериализованные имена наших полей на не соответствующие тем, которые указаны в нашем POJO, с помощью @SerializedName аннотации:
Теперь при сериализации эти имена будут использоваться вместо наших имен полей:
Это также работает наоборот – если мы получим JSON с именем и наш Студент POJO имеет имя , сопоставленное с Именем , мы десериализуем это просто отлично:
Вывод
В этом уроке мы рассмотрели, как преобразовать объект Java в объект JSON с помощью метода Gson toJSON () , а также как преобразовать объект JSON в объект Java с помощью метода Gson FromJSON () .
Мы также изучили, как включить красивую печать, а также изменить сериализованные имена полей.
Rukovodstvo
статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.
Как преобразовать объект JSON в объект Java с помощью Джексона
В этом руководстве мы рассмотрим, как преобразовать объект JSON в объект Java с помощью Jackson [https://github.com/FasterXML/jackson], чрезвычайно популярной библиотеки привязки данных для Java. В частности, мы будем работать с этим объектом JSON: <"name": "David", "position": "Software Engineer", "skilltree": ["Java", "Python", "JavaScript"], "address ": <" street ":" Street "," streetNo ":" 123 ">> Поскольку мы работаем с внешней библиотекой,
Время чтения: 2 мин.
В этом руководстве мы рассмотрим, как преобразовать объект JSON в объект Java с помощью Jackson , чрезвычайно популярной библиотеки привязки данных для Java.
В частности, мы будем работать с этим объектом JSON:
Поскольку мы работаем с внешней библиотекой, давайте добавим зависимость. Если вы используете Maven, вы можете добавить его с помощью:
Или, если вы используете Gradle, вы можете добавить:
Создание настраиваемого класса
После этого мы можем создать простой настраиваемый класс для размещения Employee из содержимого JSON:
Примечание. Если мы хотим, чтобы Джексон мог автоматически связывать свойства нашего класса и свойства в объекте JSON, они должны иметь одинаковые имена. Мы расскажем, как изменить это поведение чуть позже. Кроме того, вам понадобится пустой конструктор для создания экземпляра.
Здесь мы используем перечисление POSITION , которое выглядит так:
И объект Address
Преобразование объекта JSON в объект Java
Центральный класс Джексона — ObjectMapper . Это основной API для привязки данных к объектам, и вы все время будете использовать его с Джексоном.
Чтобы преобразовать объект JSON в объект Java, вы будете использовать метод readValue() ObjectMapper , который десериализует его в предоставленную ссылку на класс:
Выполнение этого кода приведет к:
Другой способ сообщить Джексону, в какой класс следует десериализоваться, — использовать TypeReference :
Печать этого employee также приведет к:
Оба они создают данный объект и вызывают один и тот же процесс десериализации. Таким образом, единственная разница между этими двумя вызовами заключается в том, делаете ли вы статическую или динамическую ссылку на тип.
Работа с JSON на Java (библиотека GSON)
Заметка взята с сайта Javenue, так как несет много полезной информации. Спасибо ее автору.
Заметка была дополнена, поэтому если обнаружатся неточности — прошу писать мне.
JSON, что означает JavaScript Object Notation, — это текстовый формат обмена данными, который легко читается человеком и в то же время является компактным (в отличии от того же XML формата).
По сути это набор пар “ключ-значение”, объединенных в последовательность значений(массив). Допустим мы производим выборку информацию о заказчике из БД и возвращаем сведения о нем. Пример строки в формате JSON будет выглядеть так:
Вообще, о самом формате JSON в Интернете написано более чем достаточно, ну а в этой статье я хочу рассмотреть бибилиотеку Gson для сериализации и десериализации java объектов в JSON.
1 Обзор библиотеки Gson
Gson — это небольшая java библиотека, которая позволяет конвертировать java объекты в их JSON представление, равно как и создавать объекты на основании их json представления.
Изначально Gson был разработан в Google и использовался в нескольких внтуренних проектах. Через некоторое время было принято решение отдать библиотеку в open-source, чтобы она и дальше развивалась.
1.1 Подключение GSON
Сначала подключим библиотеку. Если вы используете в качестве сборщика Gradle, добавьте новую зависимость:
Вот, что нужно прописать в файл pom.xml тем, кто использует Maven:
1.2 Использование GSON
Основным классом библиотеки есть одноименный класс Gson. Для того, чтобы создать экземпляр класса нужно воспользоваться одним из двух способов:
Первый способ создаст инстанс класса с настройками по умолчанию, а второй способ позволит применить некоторые настройки. О настройках расскажу чуть ниже.
Основные методы, которые используются для сериализации и десериализации java-объектов, называются toJson и fromJson .
2 Сериализация и десериализация в Gson
Начнем с чего-нибудь попроще:
Это так называемы примитивы JSON. А вот так их можно десериализовать:
Так как инстанс Gson не имеет внутреннего состояния, то его можно переиспользовать произвольное количество раз, а так же использовать в многопоточных приложениях.
Идем дальше. Вот таким образом можно сериализовать и десеарелизовать массив:
С объектами, которые в качестве полей содержат строки и примитивы, все тоже достаточно просто. Допустим, у нас в приложении описан следующий класс:
И экземпляр класса созданный таким способом:
Смотрим, что получается:
Обратите внимание, что при сериализации значение поля random не было сохранено. Все дело в том, что поведение библиотеки по-умолчанию не сериализует поля, помеченные модификатором transient . О том, как изменить это поведение, читайте в разделе про GsonBuilder .
3 Работа с коллекциями
Сериализация коллекций, таких как ArrayList, LinkedList, HashSet, TreeMap и других, реализована таким образом:
- метод toJson для Collection вернет массив объектов или примитивов;
- метод toJson для Map вернет ассоциативный массив.
С десериализацией все немного сложнее. Рассмотрим следующий пример:
Обратите внимание как мы определили тип для коллекции при десериализации. К сожалению, сделать это как-то проще не получится.
Допустим, вам необходимо конвертировать коллекцию, содержащую объекты различных типов. В этом случае с сериализацией проблем не возникнет, например:
А вот десереализовать такую коллекцию не получится, так как Gson не сможет найти правильные соответствия для типов данных.
Одним из самых хороших решений этой проблемы будет использование низкоуровневого API — классы JsonElement, JsonPrimitive, JsonObject и так далее. Некоторое представление о том, как это сделать, вы сможете получить в следующем разделе статьи.
4 Определяем свои правила конвертации объектов
Gson позволяет разработчикам определять свои собственные правила для сериализации и десериализации объектов. Зарегистрировать их можно с помощью метода registerTypeAdapter() .
Допустим, у нас в приложении есть следующий класс:
Для кастомного сериализатора необходимо реализовать интерфейс JsonSerializer , а для десериализаторв — соответственно JsonDeserializer . Для простоты можно создать один класс, который реализует оба эти интерфейса:
Зарегистрировать наш класс можно следующим образом:
5 Настройки Gson и класс GsonBuilder
По умолчанию результат сериализации в json будет компактным, то есть все лишние whitespace символы будут удалены. Это позволит, например, уменьшить траффик при передачи JSON объектов по сети.
Метод setPrettyPrinting у класса GsonBuilder меняет это поведение и сериализует объекты в удобную для человека форму с пробелами и переводами строк. Пример вы можете посмотреть по ссылке приведенной в начале статьи.
Еще одна полезная настройка для GsonBuilder — excludeFieldsWithModifiers . Она позволяет изменить набор несериализуемых полей при конвертации java объектов в JSON. По умолчанию игнорируются только поля с модификатором transient .
6 Пример использования GSON
Нам надо преобразовать данные JSON в Java-объект. Пусть у нас имеется класс Student , представляющий заказчика, с определенными полями: имя и курс.
Аннотация @SerializedName используется для изменения выходного имени свойства при сериализации, если это потребуется.
Итак, мы получили объект в виде строки, например такой объект может прийти приложению-клюиенту от сервера или может быть считан с файла. Для выполнения парсинга нам необходимо получить объект класса Gson , для этого удобно использовать GsonBuilder . Преобразование JSON в объект класса Student выполняется методом Gson.from() :
Например, можно считывать объекты из файла по одному. Однако, если у вас есть корректный JSON файл или сервер прислал сразу массив объектов — то их можно сразу преобразовать в массив. Например, при запросе истории погоды или курса валют за период сервер мог бы прислать вам массив однотипных объектов.
Здесь методу fromJson() мы в качестве второго параметра должны передаем тип нашей коллекции.
Парсинг JSON с помощью Jackson
Большая часть веба на сегодняшний день обменивается данными в формате JSON. Веб-серверы, веб-приложения и мобильные приложения, даже устройства IoT общаются друг с другом, используя JSON. Простой и гибкий способ обработки JSON необходим любому программному обеспечению, чтобы выжить в современном мире.
Эта статья сопровождается примером рабочего кода на GitHub.
Что такое JSON?
JSON (от англ JavaScript Object Notation) — это текстовый формат для представления структурированных данных на основе синтаксиса объектов JavaScript. Благодаря своему гибкому и простому формату он стал чрезвычайно популярным. По сути, он следует модели карты «ключ-значение», допускающей вложенные объекты и массивы:
Что такое Jackson?
Jackson в основном известен как библиотека, которая конвертирует строки JSON и простые объекты Java (англ POJO — Plain Old Java Object). Он также поддерживает многие другие форматы данных, такие как CSV, YML и XML.
Многие предпочитают Jackson благодаря его зрелости (он существует уже 13 лет) и отличной интеграции с популярными фреймворками, такими как Spring. Более того, это проект с открытым исходным кодом, который активно развивается и поддерживается широким сообществом.
Под капотом у Jackson есть три основных пакета: Streaming, Databind и Annotations. При этом Jackson предлагает нам три способа обработки преобразования JSON-POJO:
Потоковое API
Это самый быстрый подход из трех и с наименьшими накладными расходами. Он читает и записывает содержимое JSON в виде дискретных событий. API предоставляет JsonParser, который считывает JSON в POJO, и JsonGenerator, который записывает POJO в JSON.
Модель дерева
Модель дерева создает в памяти древовидное представление документа JSON. ObjectMapper отвечает за построение дерева из узлов JsonNode. Это наиболее гибкий подход, поскольку он позволяет перемещаться по дереву узлов, когда документ JSON не соответствует в достаточной мере POJO.
Привязка данных
Это позволяет нам выполнять преобразование между документами POJO и JSON с помощью средств доступа к свойствам или с помощью аннотаций. Он предлагает два типа привязки:
Простая привязка данных, которая преобразует JSON в Java Maps, Lists, Strings, Numbers, Booleans, null объекты и обратно.
Полная привязка данных, которая преобразует JSON в любой класс Java и из него.
ObjectMapper
ObjectMapper — наиболее часто используемая часть библиотеки Jackson, так как является самым простым способом преобразования между POJO и JSON. Она находится в com.fasterxml.jackson.databind .
Метод readValue() используется для преобразования (десериализации) JSON из строки, потока или файла в POJO.
С другой стороны, метод writeValue() используется для преобразования POJO в JSON (сериализация).
Способ, которым ObjectMapper определяет, какое поле JSON соответствует какому полю POJO, заключается в сопоставлении имен полей JSON с именами геттеров и сеттеров в POJO.
Это делается путем удаления частей «get» и «set» в именах геттеров и сеттеров и преобразования первого символа имени оставшегося метода в нижний регистр.
Например, предположим, у нас есть поле JSON с именем name : ObjectMapper сопоставит его с геттером getName() и сеттером setName() в POJO.
ObjectMapper является настраиваемым, и мы можем кастомизировать его в соответствии с нашими потребностями либо непосредственно через экземпляр ObjectMapper , либо с помощью аннотаций Jackson, как мы увидим позже.
Зависимости Maven
Прежде чем мы посмотрим на код, нам нужно добавить зависимость Jackson Maven jackson-databind, которая, в свою очередь, транзитивно добавляет jackson-annotations и jackson-core .
Мы также используем Lombok для обработки шаблонного кода для геттеров, сеттеров и конструкторов.
Базовая сериализация и десериализация JSON с Jackson
Давайте рассмотрим наиболее важные варианты использования Jackson с примерами кода.
Базовое преобразование POJO/JSON с использованием ObjectMapper
Давайте начнем с представления простого POJO под названием Employee:
Начнем с преобразования POJO в строку JSON:
В качестве вывода увидим следующее:
Теперь посмотрим, как преобразовать строку JSON в объект Employee с помощью ObjectMapper .
ObjectMapper также предлагает богатый API для чтения JSON из разных источников в разные форматы, давайте проверим самые важные из них.
Создание POJO из файла JSON
Это делается с помощью метода readValue() .
Файл JSON в тестовых ресурсах employee.json :
Создание POJO из массива байт в формате JSON
Создание списка POJO из JSON
Иногда документ JSON представляет собой не объект, а список объектов. Давайте посмотрим, как можно его прочитать.
Создание Map из JSON
Мы можем преобразовать JSON в Java Map , что очень удобно, если мы не знаем, чего ожидать от файла JSON, который мы пытаемся спарсить. ObjectMapper превратит имя каждой переменной в JSON в ключ для Map, а значение этой переменной — в значение по этому ключу.
Игнорирование неизвестных полей JSON
Иногда ожидаемый нами JSON может иметь дополнительные поля, не определенные в POJO. Поведение Jackson по умолчанию заключается в том, чтобы в таких случаях генерировать исключение UnrecognizedPropertyException . Однако же мы можем настроить Jackson так, чтобы он не расстраивался по поводу неизвестных полей и просто игнорировал их. Это делается путем установки FAIL_ON_UNKNOWN_PROPERTIES ObjectMapper в false.
Работа с датами in Jackson
Преобразование дат может быть непростым занятием, поскольку они могут быть представлены во многих форматах и уровнях спецификации (секунды, миллисекунды и т. д.).
Дата в JSON
Прежде чем говорить о преобразовании дат и Jackson, нам нужно поговорить о новом Date API в Java 8. Он был введен для устранения недостатков более старых java.util.Date и java.util.Calendar . В основном нас интересует использование класса LocalDate , который предлагает эффективный способ представления даты и времени.
Для этого нам нужно добавить в Jackson дополнительный модуль, чтобы он мог обрабатывать LocalDate .
Затем нам нужно сказать ObjectMapper найти и зарегистрировать новый модуль, который мы только что добавили.
В этом случае поведение Jackson по умолчанию состоит в том, чтобы показывать дату как [гггг-ММ-дд]. Таким образом, вывод будет
Однако мы можем указать Jackson, в каком формате нам нужна дата. Это можно сделать с помощью аннотации @JsonFormat .
JSON в дату
Мы можем использовать ту же конфигурацию выше, чтобы преобразовать поле JSON в дату.
Аннотации Jackson
Важную роль в настройке процесса преобразования JSON/POJO играют аннотации. Мы видели пример с преобразованием даты, где мы использовали аннотацию @JsonFormat . Аннотации влияют на то, как данные читаются, записываются или даже на то и другое. Давайте рассмотрим некоторые из этих аннотаций на основе их категорий.
Аннотации чтения
Они влияют на то, как Jackson преобразует JSON в POJO.
@JsonSetter
Это полезно, когда мы хотим сопоставить поле в строке JSON с полем в POJO, где их имена не совпадают.
@JsonAnySetter
Эта аннотация полезна в случаях, когда JSON содержит некоторые поля, не объявленные в POJO. Он используется с сеттером, который вызывается для каждого нераспознанного поля.
Аннотации записи
Они влияют на то, как Jackson преобразует POJO в JSON.
@JsonGetter
Это полезно, когда мы хотим сопоставить поле POJO с полем JSON, используя другое имя. Например, предположим, что у нас есть класс Cat с полем name , но мы хотим, чтобы его JSON-имя было catName .
@JsonAnyGetter
Эта аннотация позволяет нам использовать объект Map как источник свойств JSON. Скажем, у нас есть эта карта как поле в классе Cat .
Вывод будет следующим:
Аннотации чтения и записи
Эти аннотации влияют как на чтение, так и на запись JSON.
@JsonIgnore
Поле с аннотацией игнорируется как при записи, так и при чтении JSON.
То же самое относится и к чтению в POJO.
Предположим, у нас есть файл dog.json :
У Jackson есть еще много полезных аннотаций, которые дают нам больше контроля над процессом сериализации/десериализации. Полный их список можно найти в репозитории Jackson на Github.
Резюме
Jackson — одна из самых мощных и популярных библиотек для обработки JSON в Java.
Jackson включает три основных модуля: Streaming API, Tree Model и Data Binding.
Jackson предоставляет ObjectMapper, который легко настраивается в соответствии с потребностями, с возможностью задавать его свойства и использовать аннотации.
Приглашаем всех желающих на открытый урок «Реляционные базы данных для начинающих Java-разработчиков». На уроке поговорим о месте реляционных баз данных в архитектуре информационных систем. Рассмотрим основные компоненты и возможности РСУБД на примере PostgreSQL. Сделаем обзор основных технологий по работе с реляционными БД в Java (JDBC, JPA/Hibernate, Spring Data и др.). Регистрируйтесь по ссылке.