Как отправить json java
Для отправки JSON данных в Java можно использовать библиотеку для работы с HTTP-запросами , такую как Apache HttpClient . В данном примере будем использовать версию 4.5.13 библиотеки.
Вот пример кода для отправки JSON данных на сервер:
import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; public class JsonSender public static void main(String[] args) throws IOException String json = ""; HttpClient httpClient = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost("https://example.com/api/endpoint"); StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); httpPost.setEntity(entity); httpPost.setHeader("Accept", "application/json"); httpPost.setHeader("Content-type", "application/json"); httpClient.execute(httpPost); > >
Здесь мы создаем JSON строку и отправляем ее на сервер с помощью POST запроса.
Код создает объект HttpClient и объект HttpPost , добавляет JSON -строку в запрос, устанавливает заголовки Accept и Content-Type в application/json и отправляет запрос на сервер.
Важно убедиться, что на стороне сервера корректно обрабатываются входящие JSON данные.
Парсинг JSON с помощью Jackson
Большая часть веба на сегодняшний день обменивается данными в формате JSON. Веб-серверы, веб-приложения и мобильные приложения, даже устройства IoT общаются друг с другом, используя JSON. Простой и гибкий способ обработки JSON необходим любому программному обеспечению, чтобы выжить в современном мире.
Эта статья сопровождается примером рабочего кода на GitHub.
Что такое JSON?
JSON (от англ JavaScript Object Notation) — это текстовый формат для представления структурированных данных на основе синтаксиса объектов JavaScript. Благодаря своему гибкому и простому формату он стал чрезвычайно популярным. По сути, он следует модели карты «ключ-значение», допускающей вложенные объекты и массивы:
< "array": [ 1, 2, 3 ], "boolean": true, "color": "gold", "null": null, "number": 123, "object": < "a": "b", "c": "d" >, "string": "Hello World" >
Что такое 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:
public class JacksonTest < ObjectMapper objectMapper = new ObjectMapper(); @Test void pojoToJsonString() throws JsonProcessingException < Employee employee = new Employee("Mark", "James", 20); String json = objectMapper.writeValueAsString(employee); System.out.println(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 :
public class JacksonTest < . @Test void jsonFileToPojo() throws IOException < File file = new File("src/test/resources/employee.json"); Employee employee = objectMapper.readValue(file, Employee.class); assertThat(employee.getAge()).isEqualTo(44); assertThat(employee.getLastName()).isEqualTo("Simpson"); assertThat(employee.getFirstName()).isEqualTo("Homer"); >>
Создание 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.
public class JacksonTest < . @Test void fileToPojoWithUnknownProperties() throws IOException < File file = new File("src/test/resources/employeeWithUnknownProperties.json"); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); Employee employee = objectMapper.readValue(file, Employee.class); assertThat(employee.getFirstName()).isEqualTo("Homer"); assertThat(employee.getLastName()).isEqualTo("Simpson"); assertThat(employee.getAge()).isEqualTo(44); >>
Работа с датами 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 найти и зарегистрировать новый модуль, который мы только что добавили.
public class JacksonTest < ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules(); . @Test void orderToJson() throws JsonProcessingException < Order order = new Order(1, LocalDate.of(1900,2,1)); String json = objectMapper.writeValueAsString(order); System.out.println(json); >>
В этом случае поведение Jackson по умолчанию состоит в том, чтобы показывать дату как [гггг-ММ-дд]. Таким образом, вывод будет
Однако мы можем указать Jackson, в каком формате нам нужна дата. Это можно сделать с помощью аннотации @JsonFormat .
public class Order < private int id; @JsonFormat(pattern = "dd/MM/yyyy") private LocalDate date; >
@Test void orderToJsonWithDate() throws JsonProcessingException
JSON в дату
Мы можем использовать ту же конфигурацию выше, чтобы преобразовать поле JSON в дату.
public class JacksonTest < . @Test void fileToOrder() throws IOException < File file = new File("src/test/resources/order.json"); Order order = objectMapper.readValue(file, Order.class); assertThat(order.getDate().getYear()).isEqualTo(2000); assertThat(order.getDate().getMonthValue()).isEqualTo(4); assertThat(order.getDate().getDayOfMonth()).isEqualTo(30); >>
Аннотации Jackson
Важную роль в настройке процесса преобразования JSON/POJO играют аннотации. Мы видели пример с преобразованием даты, где мы использовали аннотацию @JsonFormat . Аннотации влияют на то, как данные читаются, записываются или даже на то и другое. Давайте рассмотрим некоторые из этих аннотаций на основе их категорий.
Аннотации чтения
Они влияют на то, как Jackson преобразует JSON в POJO.
@JsonSetter
Это полезно, когда мы хотим сопоставить поле в строке JSON с полем в POJO, где их имена не совпадают.
@NoArgsConstructor @AllArgsConstructor @Getter public class Car
public class JacksonTest < . @Test void fileToCar() throws IOException < File file = new File("src/test/resources/car.json"); Car car = objectMapper.readValue(file, Car.class); assertThat(car.getBrand()).isEqualTo("BMW"); >>
@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); >>
public class JacksonTest < . @Test void fileToUnrecognizedCar() throws IOException < File file = new File("src/test/resources/carUnrecognized.json"); Car car = objectMapper.readValue(file, Car.class); assertThat(car.getUnrecognizedFields()).containsKey("productionYear"); >>
Аннотации записи
Они влияют на то, как 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; >>
public class JacksonTest < . @Test void catToJson() throws JsonProcessingException < Cat cat = new Cat("Monica"); String json = objectMapper.writeValueAsString(cat); System.out.println(json); >>
@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
public class JacksonTest < . @Test void dogToJson() throws JsonProcessingException < Dog dog = new Dog("Max", 3); String json = objectMapper.writeValueAsString(dog); System.out.println(json); >>
То же самое относится и к чтению в POJO.
Предположим, у нас есть файл dog.json :
public class JacksonTest < . @Test void fileToDog() throws IOException < File file = new File("src/test/resources/dog.json"); Dog dog = objectMapper.readValue(file, Dog.class); assertThat(dog.getName()).isEqualTo("bobby"); assertThat(dog.getAge()).isNull(); >>
У Jackson есть еще много полезных аннотаций, которые дают нам больше контроля над процессом сериализации/десериализации. Полный их список можно найти в репозитории Jackson на Github.
Резюме
- Jackson — одна из самых мощных и популярных библиотек для обработки JSON в Java.
- Jackson включает три основных модуля: Streaming API, Tree Model и Data Binding.
- Jackson предоставляет ObjectMapper, который легко настраивается в соответствии с потребностями, с возможностью задавать его свойства и использовать аннотации.
Приглашаем всех желающих на открытый урок «Реляционные базы данных для начинающих Java-разработчиков». На уроке поговорим о месте реляционных баз данных в архитектуре информационных систем. Рассмотрим основные компоненты и возможности РСУБД на примере PostgreSQL. Сделаем обзор основных технологий по работе с реляционными БД в Java (JDBC, JPA/Hibernate, Spring Data и др.). Регистрируйтесь по ссылке.
- Блог компании OTUS
- Программирование
- Java
Как и чем парсить Json на Java?
Часто возникает потребность работы с Json, в частности его чтения и парсинга. В Java обычно ты знаешь с каким типом переменных работаешь, а при парсинге Json смущает то, что тип полей может быть любой. Какие есть способы разбора Json? Как это делать? Вот, допустим, как достать данные из Json, представленного ниже?
< "firstName": "Json", "lastName": "Smith", "age": 30, "address": < "streetAddress": "666 1nd Street", "city": "New York", "state": "NY", "postalCode": 10021 >, "phoneNumbers": [ < "type": "home", "number": "542 666-1234" >, < "type": "fax", "number": "653 666-4567" >], "friends": [ < "firstName": "Test", "lastName": "Snow", "age": 20, "phoneNumbers": [ < "type": "home", "number": "141 111-1234" >], "friends": [ < "firstName": "UnknownFirstName", "lastName": "UnknownLastName", "age": 999, "phoneNumbers": [ < "type": "home", "number": "000 000-0000" >] > ] >, < "firstName": "Flash", "lastName": "Tompson", "age": 23, "phoneNumbers": [ < "type": "home", "number": "999 111-1234" >] > ] >
Отслеживать
28.5k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков
задан 15 ноя 2017 в 13:35
Алексей Шиманский Алексей Шиманский
71.2k 12 12 золотых знаков 91 91 серебряный знак 180 180 бронзовых знаков
4 ответа 4
Сортировка: Сброс на вариант по умолчанию
Достать данные можно разными способами и, конечно, зависит от задач. Попробую рассмотреть некоторые варианты разбора Json.
Заметка: для каждого из примеров для парсинга будет взят Json из вопроса, чтобы зря не копировать в ответ.
Simple Json
Где взять: здесь / репозиторий на github / или через Maven и пр.
Это самый примитивный способ. По сути, всё, что тут есть — это JSONObject и JSONArray .
- JSONArray может включать в себя несколько объектов JSONObject , его можно обходить циклом на каждой итерации получая объект JSONObject .
- JSONObject — объект, из которого можно доставать его отдельные свойства.
Я бы использовал его для небольших Json строк, где не надо сильно заморачиваться или если не лень писать свой класс-обработчик на основе кода, который продемонстрирован ниже:
// Считываем json Object obj = new JSONParser().parse(jsonString); // Object obj = new JSONParser().parse(new FileReader("JSONExample.json")); // Кастим obj в JSONObject JSONObject jo = (JSONObject) obj; // Достаём firstName and lastName String firstName = (String) jo.get("firstName"); String lastName = (String) jo.get("lastName"); System.out.println("fio: " + firstName + " " + lastName); // Достаем массив номеров JSONArray phoneNumbersArr = (JSONArray) jo.get("phoneNumbers"); Iterator phonesItr = phoneNumbersArr.iterator(); System.out.println("phoneNumbers:"); // Выводим в цикле данные массива while (phonesItr.hasNext())
Остальная работа с вложенными массивами аналогична. Можно складывать в List, Map и пр.
GSON
Где взять: здесь / репозиторий на github / или через Maven и пр.
Позволяет парсить Json также, как и Json-simple, т.е. используя JSONObject и JSONArray (см. документацию), но имеет более мощный инструмент парсинга. Достаточно создать классы, которые повторяют структуру Json‘а. Для парсинга Json из вопроса создадим классы:
class Person < public String firstName; public String lastName; public int age; public Address address; public ListphoneNumbers; public List friends; > class Address < public String streetAddress; public String city; public String state; public int postalCode; >class Phones
Теперь достаточно написать:
Gson g = new Gson(); Person person = g.fromJson(jsonString, Person.class);
Всё! Магия! Чудо! Теперь в person лежит объект с типом Person , в котором находятся данные именно с теми типами, которые были указаны в созданных классах! Теперь можно работать с любым типом, как это привыкли всегда делать: String, Integer, List, Map и всё остальное.
// Выведет фамилии всех друзей с их телефонами for (Person friend : person.friends) < System.out.print(friend.lastName); for (Phones phone : friend.phoneNumbers) < System.out.println(" - phone type: " + phone.type + ", phone number : " + phone.number); >> // output: // Snow - phone type: home, phone number : 141 111-1234 // Tompson - phone type: home, phone number : 999 111-1234
Пример парсинга в Map :
. JSON для разбора:
< "2":< "sessions":[ < "time":"13:00", "price":"410" >, < "time":"06:40", "price":"340" >, < "time":"16:50", "price":"370" >], "name":"Кинокис-L", "locate":"Москва, Садовая-Спасская ул., 21, 56", "metro":"Красные ворота" >, "7":< "sessions":[ < "time":"06:35", "price":"190" >, < "time":"00:05", "price":"410" >], "name":"Кинокис-V", "locate":"Павелецкая пл., 2, строение 1", "metro":"Павелецкая" >, "8": < "sessions":[ < "time":"15:10", "price":"330" >], "name":"Кинокис-J", "locate":"ул. Пречистенка, 40/2", "metro":"Кропоткинская" >, "9":< "sessions":[ < "time":"13:00", "price":"600" >, < "time":"08:30", "price":"300" >, < "time":"04:00", "price":"510" >, < "time":"13:15", "price":"340" >], "name":"Кинокис-U", "locate":"Шарикоподшипниковская ул., 24", "metro":"Дубровка" > >
class Seanse < public String name; public String locate public String metro; public Listsessions; > class Sessions
. Сам разбор выглядит так:
Gson g = new Gson(); Type type = new TypeToken>()<>.getType(); Map myMap = g.fromJson(json, type);
Дополнительно в GSON можно использовать аннотации, например: исключить указанные поля при парсинге, поменять имя переменной (например не personFirstName , а fName ) и многое другое. Подробнее см. в документации.
Jackson
Где взять: здесь / репозиторий на github / или через Maven и пр.
Как и GSON он также позволяет работать используя JSONObject и JSONArray если это требуется, и тоже умеет парсить на основе предоставленных классов (см. пример ниже).
Аналогично в нем можно указывать дополнительные требования за счет аннотаций, например: не парсить указанные поля, использовать кастомный конструктор класса, поменять имя переменной (например не firstName , а fName ) и многое другое. Подробнее см. в документации.
ObjectMapper mapper = new ObjectMapper(); Person person = mapper.readValue(jsonString, Person.class); System.out.println("My fio: " + person.firstName + " " + person.lastName + " and my friends are: "); for (Person friend : person.friends) < System.out.print(friend.lastName); for (Phones phone : friend.phoneNumbers) < System.out.println(" - phone type: " + phone.type + ", phone number : " + phone.number); >> // output: // My fio: Json Smith and my friends are: // Snow - phone type: home, phone number : 141 111-1234 // Tompson - phone type: home, phone number : 999 111-1234
JsonPath
Где взять: через Maven и другие сборщики / репозиторий на github
Относится к так называемым XPath библиотекам. Её суть аналогична xpath в xml, то есть легко получать часть информации из json‘а, по указанному пути. А также позволяет фильтровать по условию.
// Выведет все фамилии друзей List friendsLastnames = JsonPath.read(jsonString, "$.friends[*].lastName"); for (String lastname : friendsLastnames) < System.out.println(lastname); >// output: // Snow // Tompson
Пример с выборкой по условию:
// Поиск друга, которому больше 22 лет List friendsWithAges = JsonPath .using(Configuration.defaultConfiguration()) .parse(jsonString) .read("$.friends[?(@.age > 22)].lastName", List.class); for (String lastname : friendsWithAges) < System.out.println(lastname); >// output: // Tompson
Отслеживать
ответ дан 15 ноя 2017 в 13:35
Алексей Шиманский Алексей Шиманский
71.2k 12 12 золотых знаков 91 91 серебряный знак 180 180 бронзовых знаков
У GSON также наличествует возможность менять поведение аннотациями
15 ноя 2017 в 14:08
Понимаю, зачем ТС задал такой вопрос и сам же на него и ответил, ибо действительно достали вопросы новичков как парсить Json. Предлагаю ответ сделать общим и на вопросы по Json далее ставить дубли со ссылкой на этот ответ.
15 ноя 2017 в 14:23
@Barmaley я бы предложил писать еще ответы, чтоб хотя бы ответ не был полотном гигантским. И еще хочу ЮрийСПб попросить чтоб отдельно написал ответы по Android, думаю там есть что-то тоже отдельно
15 ноя 2017 в 14:31
@rjhdby добавил сий нюанс в ответ.
15 ноя 2017 в 15:27
@Barmaley, для этого не надо ничего делать общим.
20 ноя 2017 в 18:56
Еще несколько вариантов
LoganSquare
LoganSquare — основана на Jackson‘s streaming API. По демонстрируемым тестам работает быстрее GSON и Jackson. Поэтому хорош для Android.
Где взять: репозиторий на github / или через Maven / Gradle и пр.
- Классы должны быть помечены аннотацией @JsonObject
- Поля должны быть помечены аннотацией @JsonField (с различными варианциями входных параметров, например @JsonField(name=»message») )
- Другие предъявляемые требования: https://github.com/bluelinelabs/LoganSquare/blob/development/docs/Models.md
@JsonObject public class Person < @JsonField(name="firstName") public String firstName; @JsonField(name="age") public int age; public void say() < System.out.println(); System.out.println("My name is " + firstName + " , I'm " + age + " years old!"); >>
String jsonString = ""; Person person = LoganSquare.parse(jsonString, Person.class); person.say(); // My name is Adam , I'm 18 years old!
Moshi
Moshi is a modern JSON library for Android and Java.
Хорош, как утверждают разработчики, для работы с Android.
Где взять: репозиторий на github / или через Maven / Gradle и пр.
-
Пример разбора Json строки в объект Person :
Moshi moshi = new Moshi.Builder().build(); JsonAdapter jsonAdapter = moshi.adapter(Person.class); Person person = jsonAdapter.fromJson(jsonStringPerson); // В person будут все данные
class Seanse < public String name; public String locate public String metro; public Listsessions; > class Sessions < public String time; public double price; >public class Main < public static void main(String[] args) throws IOException < String jsonStringForMap = "<\"2\":<\"sessions\":[<\"time\":\"13:00\",\"price\":\"410\">,< \"time\":\"06:40\",\"price\":\"340\">,< \"time\":\"16:50\",\"price\":\"370\">],\"name\":\"Кинокис-L\",\"locate\":\"Москва, Садовая-Спасская ул., 21, 56\",\"metro\":\"Красные ворота\">,\"7\":< \"sessions\":[ < \"time\":\"06:35\",\"price\":\"190\">,< \"time\":\"00:05\",\"price\":\"410\">],\"name\":\"Кинокис-V\",\"locate\":\"Павелецкая пл., 2, строение 1\",\"metro\":\"Павелецкая\">,\"8\":< \"sessions\":[ < \"time\":\"15:10\",\"price\":\"330\">],\"name\":\"Кинокис-J\",\"locate\":\"ул. Пречистенка, 40/2\",\"metro\":\"Кропоткинская\">,\"9\":< \"sessions\":[ < \"time\":\"13:00\",\"price\":\"600\">,< \"time\":\"08:30\",\"price\":\"300\">,< \"time\":\"04:00\",\"price\":\"510\">,< \"time\":\"13:15\",\"price\":\"340\">],\"name\":\"Кинокис-U\",\"locate\":\"Шарикоподшипниковская ул., 24\",\"metro\":\"Дубровка\">>"; Moshi moshi = new Moshi.Builder().build(); Type map = Types.newParameterizedType(Map.class, String.class, Seanse.class); JsonAdapter> jsonAdapter = moshi.adapter(map); Map seanseMap = jsonAdapter.fromJson(jsonStringForMap); > >
Genson
Где взять: здесь / репозиторий на github / или через Maven и пр.
За счет создания POJO (создаются классы, которые повторяют структуру Json‘а) — парсится объект из строки, распихивая по нужным полям объектов. Есть возможность фильтровать свойства, включить или исключить поля при парсинге, переименовать, возможность работы с аннотациями и пр. Подробнее в документации.
Genson genson = new Genson(); Person person = genson.deserialize(jsonString, Person.class); // В person будут все данные
List persons = genson.deserialize("[, ]", List.class); // persons - список с данными объектов
. JSON для разбора:
< "2":< "sessions":[ < "time":"13:00", "price":"410" >, < "time":"06:40", "price":"340" >, < "time":"16:50", "price":"370" >], "name":"Кинокис-L", "locate":"Москва, Садовая-Спасская ул., 21, 56", "metro":"Красные ворота" >, "7":< "sessions":[ < "time":"06:35", "price":"190" >, < "time":"00:05", "price":"410" >], "name":"Кинокис-V", "locate":"Павелецкая пл., 2, строение 1", "metro":"Павелецкая" >, "8": < "sessions":[ < "time":"15:10", "price":"330" >], "name":"Кинокис-J", "locate":"ул. Пречистенка, 40/2", "metro":"Кропоткинская" >, "9":< "sessions":[ < "time":"13:00", "price":"600" >, < "time":"08:30", "price":"300" >, < "time":"04:00", "price":"510" >, < "time":"13:15", "price":"340" >], "name":"Кинокис-U", "locate":"Шарикоподшипниковская ул., 24", "metro":"Дубровка" > >
class Seanse < public String name; public String locate public String metro; public Listsessions; > class Sessions
String jsonStringForMap = "ТУТ JSON СТРОКА, ОПИСАННАЯ ВЫШЕ"; Genson genson = new Genson(); Map seansesMap = genson.deserialize(jsonStringForMap, Map.class);
FastJson
Где взять: через Maven и другие сборщики / репозиторий на github. Непосредственно описание работы с xpath. Осторожно, ̶н̶е̶н̶о̶р̶м̶а̶т̶и̶в̶н̶а̶я̶ ̶л̶е̶к̶с̶и̶к̶а̶ китайский язык.
Относится к XPath аналогам.
Person person = JSON.parseObject(jsonString, Person.class); int age = person.age; System.out.println(age); // 30
// Выведет все фамилии друзей List friendsLastnames = (List) JSONPath.eval(person, "$.friends.lastName"); for (String lastname : friendsLastnames) < System.out.println(lastname); // Snow Tompson >// Поиск друга, которому больше 22 лет List friendsWithAges = (List) JSONPath.eval(person, "$.friends[?(@.age > 22)].lastName"); for (String lastname : friendsWithAges) < System.out.println(lastname); // Tompson >
Отслеживать
ответ дан 25 дек 2017 в 15:53
Алексей Шиманский Алексей Шиманский
71.2k 12 12 золотых знаков 91 91 серебряный знак 180 180 бронзовых знаков
JSON-P
Поддерживает сериализацию и парсинг JSON без предварительного маппинга в классах:
Maven:
javax.json javax.json-api 1.1.2 org.glassfish javax.json 1.1.2
Пример разбора строки JSON:
public static void main(String[] args) throws IOException
Пример вывода объекта в строку JSON:
public static void main(String[] args) throws IOException < System.out.println(prettyPrintJson(jsonObject, 0)); >public static String prettyPrintJson(JsonObject jsonObject, int indent) < String indentStr = getIndentStr(indent); String prettyJson = indentStr + "prettyJson = prettyJson.substring(0, prettyJson.length() - 1); prettyJson += "\n" + indentStr + " ]"; > catch (Exception e) < try < prettyJson += "\n" + prettyPrintJson(jsonObject.get(key).asJsonObject(), indent + 2); >catch (Exception ee) < prettyJson += jsonObject.get(key).toString(); >> prettyJson += ","; > prettyJson = prettyJson.substring(0, prettyJson.length() - 1); prettyJson += "\n" + indentStr + ">"; return prettyJson; > public static String getIndentStr(int indent) < String indentStr = ""; for (int i = 0; i < indent; i++) < indentStr += " "; >return indentStr; >
< "firstName": "Json", "lastName": "Smith", "age": 30, "address": < "streetAddress": "666 1nd Street", "city": "New York", "state": "NY", "postalCode": 10021 >, "phoneNumbers": [ < "type": "home", "number": "542 666-1234" >, < "type": "fax", "number": "653 666-4567" >], "friends": [ < "firstName": "Test", "lastName": "Snow", "age": 20, "phoneNumbers": [ < "type": "home", "number": "141 111-1234" >], "friends": [ < "firstName": "UnknownFirstName", "lastName": "UnknownLastName", "age": 999, "phoneNumbers": [ < "type": "home", "number": "000 000-0000" >] > ] >, < "firstName": "Flash", "lastName": "Tompson", "age": 23, "phoneNumbers": [ < "type": "home", "number": "999 111-1234" >] > ] >
Отслеживать
ответ дан 30 ноя 2017 в 15:43
user236980 user236980
Поддерживает сериализацию и парсинг JSON без предварительного маппинга в классах — потому что это ручной разбор, при котором разработчику известна структура и нужно писать велосипеды аналогично похожему Simple Json %)
30 ноя 2017 в 16:15
Когда известна структура наверно можно посмотреть ещё один sjr specification номер 367 или json-b (json binding)
26 дек 2017 в 13:30
Здесь расположена общая информация о парсерах, которая может помочь при выборе и понять, что он умеет. Текст и таблица, представленные ниже, взяты из публикации на Habrahabr: Шпаргалка Java программиста 8. Библиотеки для работы с Json, автор статьи @ВеденинВячеслав
- Data bind
- Tree Model
- Streaming API
- Аналоги XPath (дополнительный способ)
Data bind
Самый популярный и простой способ — вы просто указываете класс, который нужно преобразовать в json, может быть часть полей отмечаете аннотациями (а зачастую даже это необязательно), а библиотека сама превращает этот класс и всю его иерархию классов в json.
Плюсы: наиболее простой из всех
Минусы: скорость и память. Большинство библиотек использует рефлексию и т.п. методы работы с Java классами (хотя не все), что очевидно не очень быстро. К тому же, весь json файл сразу превращается в Java объекты, что может просто исчерпать всю доступную память, если вы попытаетесь обработать очень большой json.
Вывод: если нет проблем с производительностью, памятью и вы не собираетесь обрабатывать многогигабайтные json’ы скорее всего самый лучший способ.
Tree Model
Данный парсер представляет json в виде Java классов таких как Node или `JsonElement c иерархической структурой, а уже сам программист их обходит и получает из них информацию.
Плюсы: обычно быстрее первого способа и проще третьего
Минусы: уступает Data bind по простоте, плюс ряд библиотек способен генерить классы при Data bind, а не использовать рефлексию, в этом случае то что Tree Model будет быстрее не очевидно, к тому же не решается проблема огромных файлов и ограничения памяти.
Streaming API
Самый низкоуровневый способ, по сути программист сам вручную разбирает токены json’a. Зато никаких ограничений по памяти и в теории максимальная производительность.
Плюсы: производительность и минимальное потребление памяти
Минусы: сложность использования
Аналоги XPath
Не очень подходит, если нужно получит всю информацию из json‘a, зато позволяет написав выражение, например $.store.book[*].author получить список всех авторов всех книг из json‘a магазина. То есть легко получать часть информации из json‘а.
Плюсы: позволяет быстро получить информацию из json‘а по сложным критериям
Минусы: не очень подходит, когда нужна все информация из json‘а, не работает в обратную сторону на формирования json‘ов
Таблица библиотек и способы парсинга, которые они поддерживают:
Способ\Hазвание Fastjson Gson LoganSquare JSONjava Moshi Jackson Genson JsonPath SimpleJson Data bind Да Да Да - Да Да Да - - Tree Model - Да - Да - Да - - Да Streaming API - Да - - - Да - - - Аналоги XPath Да - - - - - - Да - Генерация классов - - Да - - - - - для Data bind* Работает со Да Да Нет - Да Да Да - static inner class** Обязательность Нет Нет Да - Нет Нет Нет - аннотаций***
* — Генерация классов для Data bind позволяет сгенерировать классы на стадии компиляции, что в теории должно давать значительный прирост производительности библиотеки,
** — Работает со static inner class имеет смысл только для случая Data bind, возможно ли сериализация и десериализация для случая статических внутренних классов (не статические внутренние классы сериализовать не рекомендуется),
*** — тоже только для случая Data bind можно ли не использовать аннотации или их использование крайне рекомендуется,
Java json parser – пример работы парсера
В этом посте мы разберем подробный пример парсера Java JSON. JSON(JavaScript Object Notation) – это простой текстовый формат, который облегчает чтение и запись. Это широко используемый формат обмена данными, поскольку его анализ и генерация просты в использовании.
В языке Java есть несколько способов обработки JSON. В этом примере мы собираемся использовать общий набор инструментов – JSON.simple – и узнаем, как анализировать каждый тип файла.

Установка среды
Перед началом написания кода программы, мы должны установить подходящую среду для компилятора, чтобы распознавать классы JSON. Если необходимо построить проект с помощью Maven, нужно добавить следующую запись в pom.xml:
com.googlecode.json-simple json-simple 1.1
Иначе необходимо добавить версию json-simple-1.1.1.jar в CLASSPATH.
Пример парсинга JSON
Разберем, как мы можем проанализировать и произвести чтение файла json, для этого нужно создать наш собственный файл, он будет называться jsonTestFile.json. Он имеет следующую структуру:
jsonTestFile.json: < "id": 1, "firstname": "Katerina", "languages": [ < "lang": "en", "knowledge": "proficient" >, < "lang": "fr", "knowledge": "advanced" >], "job": < "site": "www.hr-vector.com", "name": "Java Code" >>
Теперь необходимо создать файл Java в проекте с именем JsonParseTest и вставить следующий код.
package com.hrvector.javabasics.jsonparsertest; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Iterator; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; public class JsonParseTest < private static final String filePath = "C:\\Users\\katerina\\Desktop\\jsonTestFile.json"; public static void main(String[] args) < try < // считывание файла JSON FileReader reader = new FileReader(filePath); JSONParser jsonParser = new JSONParser(); JSONObject jsonObject = (JSONObject) jsonParser.parse(reader); // получение строки из объекта String firstName = (String) jsonObject.get("firstname"); System.out.println("The first name is: " + firstName); // получение номера из объекта long jsonObject.get("id"); System.out.println("The id is: " + id); // получение массива JSONArray lang= (JSONArray) jsonObject.get("languages"); // берем элементы массива for(int i=0; iIterator i = lang.iterator(); // берем каждое значение из массива json отдельно while (i.hasNext()) < JSONObject innerObj = (JSONObject) i.next(); System.out.println("language "+ innerObj.get("lang") + " with level " + innerObj.get("knowledge")); >// обрабатываем структуру в объекте JSONObject structure = (JSONObject) jsonObject.get("job"); System.out.println("Into job structure, name: " + structure.get("name")); > catch (FileNotFoundException ex) < ex.printStackTrace(); >catch (IOException ex) < ex.printStackTrace(); >catch (ParseException ex) < ex.printStackTrace(); >catch (NullPointerException ex) < ex.printStackTrace(); >> >
Объясним данный код. После создания экземпляра JSONParser мы создаем объект JSONObject.
Он содержит коллекцию пар ключ-значение, из которых мы можем получить каждое значение. Чтобы распарсить объекты, вызывается метод get() экземпляра JSONObject, определяющий указанный ключ в качестве аргумента.
Важно применить подходящий метод. Для типов массивов в файле json используется JSONArray, который представляет упорядоченную последовательность значений. В программном коде итератор должен использоваться для получения каждого значения массива json.
Структура в файле предполагает создание нового объекта JSONObject для получения значений.
Полученный результат парсинга приведен ниже.
Output: The first name is: Katerina The id is: 1 The 0 element of the array: The 1 element of the array: language en with level proficient language fr with level advanced Into job structure, name: Java Code
Метод с использованием JsonPATH
Два приведенных выше примера требуют полной десериализации JSON в объект Java перед получением значения. Другой альтернативой является использование JsonPATH, который похож на XPath для JSON и позволяет обходить объекты JSON.
Вам нужно добавить JsonPATH, которую можно получить из репозитория maven.(https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path)
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); >> >

Средняя оценка 3.3 / 5. Количество голосов: 21
Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.
Или поделись статьей
Видим, что вы не нашли ответ на свой вопрос.
Помогите улучшить статью.
Напишите комментарий, что можно добавить к статье, какой информации не хватает.
