Продолжается набор новой группы на курс Enterprise Patterns! Старт курса 02.12.2024. Регистрируйтесь со скидкой 30% до 31.10.2024!
Узнать больше
14.10.2024
10 минут чтения

Как парсить JSON в Java?

JSON (JavaScript Object Notation) — это текстовый формат обмена данными, который прост, понятен и легко читается как человеком, так и машиной. Он основан на подмножестве языка JavaScript, но не зависит от языка программирования, что делает его идеальным для передачи данных между сервером и клиентом в веб-приложениях. Благодаря своей простоте, JSON стал чрезвычайно популярным форматом для хранения и передачи данных в Интернете, заменив XML.

В современных Java-приложениях JSON широко используется для сериализации и десериализации данных, то есть для преобразования объектов в формат JSON и наоборот. Это позволяет легко интегрировать Java-приложения с другими сервисами, обмениваться данными между различными компонентами системы, а также хранить данные в файлах или базах данных в удобном и компактном формате. JSON стал стандартом де-факто для API и веб-сервисов, что делает его незаменимым инструментом для любого Java-разработчика.

Для работы с JSON в Java существует несколько популярных библиотек, каждая из которых имеет свои особенности, преимущества и недостатки. Самыми известными из них являются Jackson, Gson и JSON-B которые мы сейчас и рассмотрим. Но сначала рекомендация по обучению на курсах программирования. Если хочешь стать профи в сфере разработки — тебе в FoxmindEd. Академия, которая реально обучает.

Хотите освоить профессию Java Developer? Присоединяйтесь к программе «От 0 до Strong Java Junior за 12 месяцев». Воспользуйтесь выгодным предложением от FoxmindEd!
Зарегистрироваться

Jackson

Jackson предоставляет несколько основных классов и методов для работы с JSON, среди которых самым важным является класс ObjectMapper. Этот класс отвечает за преобразование JSON в Java-объекты и наоборот.

  • ObjectMapper: Основной класс для парсинга JSON. Он обеспечивает все необходимые методы для преобразования между JSON и Java-объектами.
  • readValue: Метод, используемый для десериализации JSON в Java-объект.
  • writeValueAsString: Метод, используемый для сериализации Java-объекта в JSON.

Рассмотрим простой пример, где мы парсим JSON в Java-объект и обратно сериализуем этот объект в JSON. Сначала нам нужно создать класс, который будет отображать JSON, который мы хотим распарсить.

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

@Getter

@Setter

@NoArgsConstructor

@AllArgsConstructor

public class User {

   private Integer id;

   private String name;

   private int age;

   private String email;

}
Смотреть больше

Примечание: не забудьте добавить к классу User конструктор без параметров иначе в методе readValue получите ошибку — InvalidDefinitionException.

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
   public static void main(String[] args) {
       try {
           // JSON строка
           String jsonString = "{\"id\":1,\"name\":\"John Doe\",\"age\":30,\"email\":\"johndoe@example.com\"}";

           ObjectMapper objectMapper = new ObjectMapper();

           // Парсим JSON в Java-объект
           User user = objectMapper.readValue(jsonString, User.class);

           System.out.println("Іd: " + user.getId());
           System.out.println("Ім'я: " + user.getName());
           System.out.println("Вік: " + user.getAge());
           System.out.println("Email: " + user.getEmail());

           // Сериализуем Java-объект в JSON
           String jsonOutput = objectMapper.writeValueAsString(user);
           System.out.println("Серіалізований JSON: " + jsonOutput);

       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}
Смотреть больше

Интересно, что будет, а если мы не хотим десеризовать определенные поля JSON? Давайте добавим еще одно поле в JSON, но класс User останется без изменений.

//Добавили 'phone' в JSON 

String jsonString = "{\"id\":1,\"name\":\"John Doe\"," +

       "\"age\":30,\"email\":\"johndoe@example.com\",\"phone\":\"+1234567890\"}";

После запуска кода мы получим ошибку UnrecognizedPropertyException. Ведь поля phone нет в классе User и ObjectMapper не знает, что с этим полем делать.

Чтобы этого избежать можно настроить ObjectMapper таким образом, чтобы он игнорировал неизвестные поля:

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Или достаточно добавить аннотацию над классом User:

@JsonIgnoreProperties(ignoreUnknown = true)

Gson

Gson предоставляет простые в использовании методы для сериализации и десериализации данных:

  • Gson: Основной класс, который отвечает за сериализацию и десериализацию JSON.
  • fromJson: Метод для преобразования JSON в Java-объект. Он принимает JSON-строку и класс, в который этот JSON должен быть преобразован.
  • toJson: Метод для преобразования Java-объекта в JSON-строку.

Важно отметить, что в отличие от ObjectMapper из библиотеки Jackson, который по умолчанию выбрасывает исключение при наличии неизвестных полей в JSON, Gson по умолчанию игнорирует такие поля и не вызывает ошибок. Это означает, что если в JSON присутствует поле, которого нет в соответствующем Java-классе, Gson просто пропустит это поле без каких-либо последствий. Такой подход делает Gson более гибким и устойчивым к изменениям структуры JSON, но также может привести к тому, что вы не заметите ошибок в данных, если какие-то поля неожиданно изменятся или будут добавлены.

Класс User оставляем без изменений. Только замечу, что для Gson не нужно добавлять в класс дефолтный (пустой) конструктор, как мы делали это с ObjectMapper.

import com.google.gson.Gson;

public class Main {

   public static void main(String[] args) {

       String jsonString = "{\"id\":1,\"name\":\"John Doe\",\"age\":30,\"email\":\"johndoe@example.com\"}";

       Gson gson = new Gson();

       User user = gson.fromJson(jsonString, User.class);

       System.out.println("Іd: " + user.getId());

       System.out.println("Имя: " + user.getName());

       System.out.println("Возраст: " + user.getAge());

       System.out.println("Email: " + user.getEmail());

       String jsonOutput = gson.toJson(user);

       System.out.println("Сериализованный JSON: " + jsonOutput);

   }

}
Смотреть больше

Gson позволяет настраивать процесс парсинга с помощью аннотаций. Самые распространенные аннотации:

  • @SerializedName: Используется для указания альтернативного имени поля в JSON.
  • @Expose: Используется для контроля сериализации и десериализации полей. Например, если использовать @Expose(serialize = false), то поле будет исключено из сериализации, но останется доступным для десериализации. Это может быть полезно, когда некоторые данные нужно скрыть при сериализации, но при этом их необходимо извлекать из JSON при десериализации.

Добавим новые аннотации к классу User

import com.google.gson.annotations.Expose;

import com.google.gson.annotations.SerializedName;

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.Setter;

@Getter

@Setter

@AllArgsConstructor

public class User {

   @SerializedName("user_id")

   @Expose

   private Integer id;

   @Expose(serialize = false)

   private String name;

   @Expose

   private int age;

   @Expose

   private String email;

}

import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

public class Main {

   public static void main(String[] args) {

       // JSON строка

       String jsonString = "{\"user_id\":1,\"name\":\"John Doe\",\"age\":30,\"email\":\"johndoe@example.com\"}";

       // Создание экземпляра Gson с учетом @Expose

       Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

       User user = gson.fromJson(jsonString, User.class);

       System.out.println("Іd: " + user.getId());

       System.out.println("Name: " + user.getName());

       System.out.println("Age: " + user.getAge());

       System.out.println("Email: " + user.getEmail());

       // Сериализируем Java-объект у JSON

       String jsonOutput = gson.toJson(user);

       System.out.println("Сериализованный JSON: " + jsonOutput); // не будет содержать поля name

   }

}
Смотреть больше

JSON-B

JSON-B (Java API for JSON Binding) — это официальный стандарт Java для сериализации и десериализации JSON в Java-объекты и наоборот. JSON-B входит в состав Java EE (Enterprise Edition) и является частью спецификации Jakarta EE, что делает его естественным выбором для корпоративных Java-приложений, особенно тех, которые используют Java EE или Jakarta EE. JSON-B предоставляет простой и унифицированный API для работы с JSON, что делает его удобным для использования в крупных проектах с четкими стандартами.

Для работы с JSON-B используется несколько основных классов и методов:

  • Jsonb: Это основной интерфейс, который предоставляет методы для сериализации и десериализации объектов.
  • JsonbBuilder: Класс для создания экземпляра Jsonb.
  • fromJson: Метод для десериализации JSON-строки в Java-объект.
  • toJson: Метод для сериализации Java-объекта в JSON-строку.
import jakarta.json.bind.annotation.JsonbProperty;

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

@Getter

@Setter

@AllArgsConstructor

@NoArgsConstructor

public class User {

   @JsonbProperty("user_id")

   private Integer id;

   private String name;

   private int age;

   private String email;

}

import jakarta.json.bind.Jsonb;

import jakarta.json.bind.JsonbBuilder;

public class Main {

   public static void main(String[] args) {

       String jsonString = "{\"user_id\":1,\"name\":\"John Doe\",\"age\":30,\"email\":\"johndoe@example.com\"}";

       Jsonb jsonb = JsonbBuilder.create();

       User user = jsonb.fromJson(jsonString, User.class);

       System.out.println("Id: " + user.getId());

       System.out.println("Name: " + user.getName());

       System.out.println("Age: " + user.getAge());

       System.out.println("Email: " + user.getEmail());

       String jsonOutput = jsonb.toJson(user);

       System.out.println("Сериализованный JSON: " + jsonOutput);

   }

}
Смотреть больше

Дополнительно

Обработка сложных структур

До этого мы рассматривали пример, где JSON представлял собой простой объект с несколькими основными полями. Однако в реальных приложениях часто возникает необходимость работать с более сложными структурами, которые содержат массивы и вложенные объекты. Наш обновленный пример:

{

  "id": 1,

  "name": "John Doe",

  "age": 30,

  "email": "johndoe@example.com",

  "phones": ["+1234567890", "+0987654321"],

  "address": {

    "street": "123 Main St",

    "city": "Anytown"

  },

  "additionalInfo": {

    "nickname": "JD",

    "hobbies": "coding"

  }

}
Смотреть больше

Примечание: поле additionalInfo в этом примере представляет собой динамически изменяемые данные. Это означает, что конкретные ключи, такие как «nickname» и «hobbies», могут изменяться или дополняться другими данными в разных сценариях. Поэтому вы не сможете просто создать статические поля класса для каждого возможного ключа.

Подпишитесь на наш Ютуб-канал! Полезные видео для программистов уже ждут вас! YouTube
Выберите свой курс! Путь к карьере программиста начинается здесь! Посмотреть

Что ж, прежде всего, давайте обновим наш класс User в соответствии с новым JSON. Квадратные скобки после phones указывают на наличие массива, поэтому для хранения телефонов мы используем тип List<String>. Поле address в JSON является вложенным объектом, который содержит информацию об улице и городе. Для его отображения мы создадим отдельный класс Address, где каждое поле будет представлено соответствующим типом.

Что касается поля additionalInfo, это особый случай. В JSON оно представлено как объект, но его ключи и значения могут меняться динамически. Поскольку мы не знаем заранее, какие именно ключи могут присутствовать, мы используем Map<String, Object>. Это предоставляет нам гибкость для хранения произвольных пар «ключ-значение», которые могут меняться в зависимости от ситуации.

@Getter

@Setter

@AllArgsConstructor

@NoArgsConstructor

public class User {

   private Integer id;

   private String name;

   private int age;

   private String email;

   private List<String> phones;

   private Address address;

   private Map<String, Object> additionalInfo;

   @Getter

   @Setter

   @AllArgsConstructor

   @NoArgsConstructor

   public static class Address {

       private String street;

       private String city;

   }

}
Смотреть больше

Для парсинга используем ObjectMapper:

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

// Парсим JSON в Java-объект

User user = objectMapper.readValue(jsonString, User.class);

// Сериализуем Java-объект в JSON

String jsonOutput = objectMapper.writeValueAsString(user);

System.out.println("Сериализованный JSON: " + jsonOutput);

Вывод

Парсинг JSON в Java является важной частью разработки современных приложений, где обмен данными между компонентами или сервисами осуществляется с помощью этого популярного формата. Важно понимать основные библиотеки для работы с JSON, такие как Jackson, Gson и JSON-B, каждая из которых имеет свои преимущества и особенности использования. Выбор библиотеки зависит от конкретных требований вашего проекта и удобства их использования.

Не менее важной является настройка поведения библиотеки в случае некорректного формата JSON. Это позволяет избежать неожиданных сбоев и обеспечить более надежную обработку данных. Использование встроенных механизмов для обработки ошибок или настройка библиотеки таким образом, чтобы она игнорировала неизвестные поля, может значительно повысить устойчивость приложения.

Подытоживая, парсинг JSON в Java — это не просто выбор библиотеки. Это также понимание того, как настроить ее под конкретные требования, обрабатывать ошибки и эффективно работать с большими объемами данных. Следуя этим принципам, вы сможете создавать надежные и эффективные приложения, которые будут легко справляться с любыми задачами, связанными с обработкой JSON.

FAQ
Как парсить JSON в Java?

Для парсинга JSON в Java используют популярные библиотеки, такие как Jackson, Gson, или JSON-B. Они позволяют легко преобразовывать JSON в Java-объекты и наоборот.

Что такое ObjectMapper в Jackson?

ObjectMapper - это класс библиотеки Jackson, который отвечает за преобразование JSON в Java-объекты и обратно.

Как избежать ошибки при парсинге JSON с неизвестными полями?

В Jackson можно использовать метод configure или аннотацию @JsonIgnoreProperties.

Чем отличается Gson от Jackson?

Gson автоматически игнорирует неизвестные поля в JSON, тогда как Jackson по умолчанию выбрасывает исключение.

Как парсить JSON в Java с использованием JSON-B?

Для этого используется класс Jsonb, который позволяет сериализировать и десериализировать объекты из JSON.

Как обрабатывать вложенные объекты или массивы в JSON?

Вложенные объекты отображаются отдельными классами, а массивы - через коллекции, например, List для массивов строк.

🤔 Остались вопросы о парсинге JSON в Java? - смело задавайте ниже! 💬

Добавить комментарий

Ваш имейл не будет опубликован. Обязательные поля отмечены *

Сохранить моё имя, имейл и адрес сайта в этом браузере для будущих комментариев