Gymterview
middle

Как работать с JSON в Java без библиотек и с Jakarta JSON-P/JSON-B?

В Jakarta EE существуют два стандартных API: JSON-P (JSON Processing) для низкоуровневого парсинга и JSON-B (JSON Binding) для привязки к объектам. Оба входят в спецификацию Jakarta EE, но на практике Jackson используется значительно чаще.

JSON-P (Jakarta JSON Processing)

Низкоуровневый API для парсинга, генерации и трансформации JSON. Работает на двух уровнях: потоковом (JsonParser/JsonGenerator) и объектном (JsonObject/JsonArray).

Пример JSON-P: построение и чтение JSON
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonWriter;
import java.io.StringReader;
import java.io.StringWriter;

public class JsonPExample {
    public static void main(String[] args) {
        // Построение JSON-объекта
        JsonObject json = Json.createObjectBuilder()
                .add("name", "Иван")
                .add("age", 30)
                .add("skills", Json.createArrayBuilder()
                        .add("Java")
                        .add("Spring")
                        .build())
                .build();

        // Запись в строку
        StringWriter sw = new StringWriter();
        try (JsonWriter writer = Json.createWriter(sw)) {
            writer.writeObject(json);
        }

        // Чтение из строки
        String input = """
            {"name":"Мария","age":25}
            """;
        try (JsonReader reader = Json.createReader(new StringReader(input))) {
            JsonObject obj = reader.readObject();
            String name = obj.getString("name");  // "Мария"
            int age = obj.getInt("age");           // 25
        }
    }
}

JSON-B (Jakarta JSON Binding)

Высокоуровневый API — аналог Jackson/Gson в мире Jakarta EE. Автоматическая привязка JSON к Java-объектам.

Пример JSON-B: аннотации и маппинг
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.annotation.JsonbProperty;
import jakarta.json.bind.annotation.JsonbTransient;
import jakarta.json.bind.annotation.JsonbDateFormat;

public class Employee {
    @JsonbProperty("full_name")
    private String name;

    @JsonbTransient
    private String internalCode;

    @JsonbDateFormat("dd.MM.yyyy")
    private LocalDate hireDate;
}

// Использование
JsonbConfig config = new JsonbConfig()
        .withFormatting(true)
        .withNullValues(false);

try (Jsonb jsonb = JsonbBuilder.create(config)) {
    String json = jsonb.toJson(employee);          // Сериализация
    Employee restored = jsonb.fromJson(json, Employee.class); // Десериализация
}

Сравнение подходов

Критерий JSON-P JSON-B Jackson
Уровень Низкоуровневый (парсинг) Высокоуровневый (binding) Оба
Стандарт Jakarta EE Jakarta EE Де-факто стандарт
Гибкость Высокая Средняя Очень высокая
Экосистема Ограниченная Ограниченная Огромная (модули)
Spring Boot Не по умолчанию Не по умолчанию По умолчанию
Реализация Eclipse Parsson Eclipse Yasson Встроена

Частые ошибки

  • Путаница между javax.json (старый Java EE) и jakarta.json (новый Jakarta EE) — пакеты несовместимы
  • Попытка использовать JSON-P для сложного маппинга — для этого нужен JSON-B или Jackson
  • Отсутствие реализации в classpath — JSON-P/JSON-B это интерфейсы, нужна реализация (Parsson, Yasson)
  • Смешивание аннотаций JSON-B и Jackson — они не взаимозаменяемы

На собеседовании: достаточно знать, что JSON-P/JSON-B существуют как часть Jakarta EE, и объяснить разницу: JSON-P — низкоуровневый парсинг, JSON-B — object binding. На практике даже в Jakarta EE проектах многие используют Jackson.