- How to Parse JSON in Java
- Parse JSON Using org.json
- Parse JSON Using Gson
- Parse JSON Using JsonPATH
- Парсинг JSON с помощью Jackson
- Что такое JSON?
- Что такое Jackson?
- ObjectMapper
- Зависимости Maven
- Базовая сериализация и десериализация JSON с Jackson
- Базовое преобразование POJO/JSON с использованием ObjectMapper
- Создание POJO из файла JSON
- Создание POJO из массива байт в формате JSON
- Создание списка POJO из JSON
- Создание Map из JSON
- Игнорирование неизвестных полей JSON
- Работа с датами in Jackson
- Дата в JSON
- JSON в дату
- Аннотации Jackson
- Аннотации чтения
- @JsonSetter
- @JsonAnySetter
- Аннотации записи
- @JsonGetter
- @JsonAnyGetter
- Аннотации чтения и записи
- @JsonIgnore
- Резюме
How to Parse JSON in Java
Last updated: 08 November 2019 In this tutorial we will look at how to parse JSON in Java using different libraries. JSON stands for JavaScript Object Notation, and it is based on a subset of JavaScript. As a data-exchange format, it is widely used in web programming. Here we show how to parse JSON in Java using the org.json library. A JSON object is an unordered set of key/value pairs. A JSON array is an ordered collection of values. The values themselves could be objects or arrays. We will be parsing this JSON as an example to retrieve values for pageName , pagePic and post_id
Parse JSON Using org.json
To use org.json to parse JSON in Java, you need to add the library as a dependency. This can be fetched from Maven repository
import org.json.JSONArray; import org.json.JSONObject; public class ParseJSON < static String json = ". "; public static void main(String[] args) < JSONObject obj = new JSONObject(json); String pageName = obj.getJSONObject("pageInfo").getString("pageName"); System.out.println(pageName); JSONArray arr = obj.getJSONArray("posts"); for (int i = 0; i < arr.length(); i++) < String post_id = arr.getJSONObject(i).getString("post_id"); System.out.println(post_id); >> >
Parse JSON Using Gson
In order to use Gson to parse JSON in Java, you need to add the library as a dependency. You can get the latest version from Maven repository
The below example shows how to Parse the above JSON with Gson.
import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; public class ParseJSON < static String json = ". "; public static void main(String[] args) < JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject(); String pageName = jsonObject.getAsJsonObject("pageInfo").get("pageName").getAsString(); System.out.println(pageName); JsonArray arr = jsonObject.getAsJsonArray("posts"); for (int i = 0; i < arr.size(); i++) < String post_id = arr.get(i).getAsJsonObject().get("post_id").getAsString(); System.out.println(post_id); >> >
Like the previous example, the . needs to be replaced by the JSON string.
Parse JSON Using JsonPATH
The above two examples require a full deserialization of the JSON into a Java object before accessing the value in the property of interest. Another alternative, which does not go this route is to use JsonPATH which is like XPath for JSON and allows traversing of JSON objects.
Like before, you need to add JsonPATH as a dependency, which can be fetched from Maven repository
For example, to parse the above JSON we can use:
import com.jayway.jsonpath.JsonPath; public class ParseJSON < static String json = ". "; public static void main(String[] args) < String pageName = JsonPath.read(json, "$.pageInfo.pageName"); System.out.println(pageName); Integer posts = JsonPath.read(json, "$.posts.length()"); for(int i=0; i < posts; i++) < String post_id = JsonPath.read(json, "$.posts[" + i + "].post_id"); System.out.println(post_id); >> >
Парсинг 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 .
com.fasterxml.jackson.core jackson-databind 2.13.3
Мы также используем Lombok для обработки шаблонного кода для геттеров, сеттеров и конструкторов.
Базовая сериализация и десериализация JSON с Jackson
Давайте рассмотрим наиболее важные варианты использования Jackson с примерами кода.
Базовое преобразование POJO/JSON с использованием ObjectMapper
Давайте начнем с представления простого POJO под названием Employee:
@Getter @AllArgsConstructor @NoArgsConstructor public class Employee
Начнем с преобразования POJO в строку JSON:
В качестве вывода увидим следующее:
Теперь посмотрим, как преобразовать строку JSON в объект Employee с помощью ObjectMapper .
public class JacksonTest < . @Test void jsonStringToPojo() throws JsonProcessingException < String employeeJson = ""; Employee employee = objectMapper.readValue(employeeJson, Employee.class); assertThat(employee.getFirstName()).isEqualTo("Jalil"); > >
ObjectMapper также предлагает богатый API для чтения JSON из разных источников в разные форматы, давайте проверим самые важные из них.
Создание POJO из файла JSON
Это делается с помощью метода readValue() .
Файл JSON в тестовых ресурсах employee.json :
Создание POJO из массива байт в формате JSON
public class JacksonTest < . @Test void byteArrayToPojo() throws IOException < String employeeJson = ""; Employee employee = objectMapper.readValue(employeeJson.getBytes(), Employee.class); assertThat(employee.getFirstName()).isEqualTo("Jalil"); > >
Создание списка POJO из JSON
Иногда документ JSON представляет собой не объект, а список объектов. Давайте посмотрим, как можно его прочитать.
public class JacksonTest < . @Test void fileToListOfPojos() throws IOException < File file = new File("src/test/resources/employeeList.json"); ListemployeeList = objectMapper.readValue(file, new TypeReference<>()<>); assertThat(employeeList).hasSize(2); assertThat(employeeList.get(0).getAge()).isEqualTo(33); assertThat(employeeList.get(0).getLastName()).isEqualTo("Simpson"); assertThat(employeeList.get(0).getFirstName()).isEqualTo("Marge"); > >
Создание Map из JSON
Мы можем преобразовать JSON в Java Map , что очень удобно, если мы не знаем, чего ожидать от файла JSON, который мы пытаемся спарсить. ObjectMapper превратит имя каждой переменной в JSON в ключ для Map, а значение этой переменной — в значение по этому ключу.
public class JacksonTest < . @Test void fileToMap() throws IOException < File file = new File("src/test/resources/employee.json"); Mapemployee = objectMapper.readValue(file, new TypeReference<>()<>); assertThat(employee.keySet()).containsExactly("firstName", "lastName", "age"); assertThat(employee.get("firstName")).isEqualTo("Homer"); assertThat(employee.get("lastName")).isEqualTo("Simpson"); assertThat(employee.get("age")).isEqualTo(44); > >
Игнорирование неизвестных полей 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 .
com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.13.3
Затем нам нужно сказать ObjectMapper найти и зарегистрировать новый модуль, который мы только что добавили.
В этом случае поведение Jackson по умолчанию состоит в том, чтобы показывать дату как [гггг-ММ-дд]. Таким образом, вывод будет
Однако мы можем указать Jackson, в каком формате нам нужна дата. Это можно сделать с помощью аннотации @JsonFormat .
@Test void orderToJsonWithDate() throws JsonProcessingException
JSON в дату
Мы можем использовать ту же конфигурацию выше, чтобы преобразовать поле JSON в дату.
Аннотации Jackson
Важную роль в настройке процесса преобразования JSON/POJO играют аннотации. Мы видели пример с преобразованием даты, где мы использовали аннотацию @JsonFormat . Аннотации влияют на то, как данные читаются, записываются или даже на то и другое. Давайте рассмотрим некоторые из этих аннотаций на основе их категорий.
Аннотации чтения
Они влияют на то, как Jackson преобразует JSON в POJO.
@JsonSetter
Это полезно, когда мы хотим сопоставить поле в строке JSON с полем в POJO, где их имена не совпадают.
@NoArgsConstructor @AllArgsConstructor @Getter public class Car
@JsonAnySetter
Эта аннотация полезна в случаях, когда JSON содержит некоторые поля, не объявленные в POJO. Он используется с сеттером, который вызывается для каждого нераспознанного поля.
public class Car < @JsonSetter("carBrand") private String brand; private MapunrecognizedFields = new HashMap<>(); @JsonAnySetter public void allSetter(String fieldName, String fieldValue) < unrecognizedFields.put(fieldName, fieldValue); >>
Аннотации записи
Они влияют на то, как Jackson преобразует POJO в JSON.
@JsonGetter
Это полезно, когда мы хотим сопоставить поле POJO с полем JSON, используя другое имя. Например, предположим, что у нас есть класс Cat с полем name , но мы хотим, чтобы его JSON-имя было catName .
@NoArgsConstructor @AllArgsConstructor public class Cat < private String name; @JsonGetter("catName") public String getName() < return name; >>
@JsonAnyGetter
Эта аннотация позволяет нам использовать объект Map как источник свойств JSON. Скажем, у нас есть эта карта как поле в классе Cat .
@NoArgsConstructor @AllArgsConstructor public class Cat < private String name; @JsonAnyGetter Mapmap = Map.of( "name", "Jack", "surname", "wolfskin" ); . >
@Test void catToJsonWithMap() throws JsonProcessingException
Аннотации чтения и записи
Эти аннотации влияют как на чтение, так и на запись JSON.
@JsonIgnore
Поле с аннотацией игнорируется как при записи, так и при чтении JSON.
@AllArgsConstructor @NoArgsConstructor @Getter public class Dog
То же самое относится и к чтению в 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 и др.). Регистрируйтесь по ссылке.