1. Обзор
Долгое время не было стандарта для обработки JSON в Java. Наиболее распространенные библиотеки, используемые для обработки JSON - это Джексон и Гсон.
Недавно в Java EE7 был добавлен API для анализа и генерации JSON ( JSR 353: Java API для обработки JSON ).
И наконец, в выпуске JEE 8 появился стандартизированный API ( JSR 367: Java API для привязки JSON (JSON-B) ).
На данный момент его основные реализации - Eclipse Yasson (RI) и Apache Johnzon .
2. JSON-B API
2.1. Maven Dependency
Давайте начнем с добавления необходимой зависимости.
Имейте в виду, что во многих случаях будет достаточно включить зависимость для выбранной реализации, а javax.json.bind-api будет включен транзитивно:
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
</dependency>
Самую последнюю версию можно найти по адресу Maven Central .
3. Использование Eclipse Yasson
-
Eclipse Yasson - официальная справочная реализация ** JSON Binding API ( JSR-367 ).
3.1. Maven Dependency
Чтобы использовать его, нам нужно включить следующие зависимости в наш проект Maven:
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.2</version>
</dependency>
Самые последние версии можно найти по адресу Maven Central.
4. Использование Apache Johnzon
Другая реализация, которую мы можем использовать, - это Apache Johnzon, которая соответствует API-интерфейсам JSON-P (JSR-353) и JSON-B (JSR-367).
4.1. Maven Dependency
Чтобы использовать его, нам нужно включить следующие зависимости в наш проект Maven:
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-json__1.1__spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.apache.johnzon</groupId>
<artifactId>johnzon-jsonb</artifactId>
<version>1.1.4</version>
</dependency>
Самые последние версии можно найти по адресу Maven Central.
5. Особенности API
API предоставляет аннотации для настройки сериализации/десериализации.
Давайте создадим простой класс и посмотрим, как выглядит пример конфигурации:
public class Person {
private int id;
@JsonbProperty("person-name")
private String name;
@JsonbProperty(nillable = true)
private String email;
@JsonbTransient
private int age;
@JsonbDateFormat("dd-MM-yyyy")
private LocalDate registeredDate;
private BigDecimal salary;
@JsonbNumberFormat(locale = "en__US", value = "#0.0")
public BigDecimal getSalary() {
return salary;
}
//standard getters and setters
}
После сериализации объект этого класса будет выглядеть так:
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registeredDate":"07-09-2019",
"salary":"1000.0"
}
Аннотации, используемые здесь:
-
@ JsonbProperty - который используется для указания имени настраиваемого поля
-
@ JsonbTransient - когда мы хотим игнорировать поле во время
десериализации/сериализации ** @ JsonbDateFormat - когда мы хотим определить формат отображения
Дата ** @ JsonbNumberFormat - для указания формата отображения числовых
ценности ** @ JsonbNillable - для включения сериализации нулевых значений
5.1. Сериализация и десериализация
Прежде всего, чтобы получить JSON-представление нашего объекта, нам нужно использовать класс JsonbBuilder и его метод toJson () .
Для начала давайте создадим простой объект Person , например:
Person person = new Person(
1,
"Jhon",
"[email protected]",
20,
LocalDate.of(2019, 9, 7),
BigDecimal.valueOf(1000));
И создайте экземпляр класса Jsonb :
Jsonb jsonb = JsonbBuilder.create();
Затем мы используем метод toJson :
String jsonPerson = jsonb.toJson(person);
Чтобы получить следующее представление JSON:
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registeredDate":"07-09-2019",
"salary":"1000.0"
}
Если мы хотим сделать преобразование другим способом, мы можем использовать метод fromJson :
Person person = jsonb.fromJson(jsonPerson, Person.class);
Естественно, мы также можем обрабатывать коллекции:
List<Person> personList = Arrays.asList(...);
String jsonArrayPerson = jsonb.toJson(personList);
Чтобы получить следующее представление JSON:
----[
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registeredDate":"09-09-2019",
"salary":"1000.0"
},
{
"email":"[email protected]",
"id":2,
"person-name":"Jhon",
"registeredDate":"09-09-2019",
"salary":"1500.0"
},
...]----
Для преобразования массива JSON в List мы будем использовать API fromJson :
List<Person> personList = jsonb.fromJson(
personJsonArray,
new ArrayList<Person>(){}.getClass().getGenericSuperclass()
);
5.2. Настраиваемое сопоставление с JsonbConfig
Класс JsonbConfig позволяет нам настроить процесс отображения для всех классов.
Например, мы можем изменить стратегии именования по умолчанию или порядок свойств.
Теперь мы будем использовать стратегию LOWER CASE WITH UNDERSCORES__:
JsonbConfig config = new JsonbConfig().withPropertyNamingStrategy(
PropertyNamingStrategy.LOWER__CASE__WITH__UNDERSCORES);
Jsonb jsonb = JsonbBuilder.create(config);
String jsonPerson = jsonb.toJson(person);
Чтобы получить следующее представление JSON:
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registered__date":"07-09-2019",
"salary":"1000.0"
}
Теперь мы изменим порядок свойств с помощью стратегии REVERSE . Используя эту стратегию, порядок свойств в порядке, обратном лексикографическому. Это также можно настроить во время компиляции с помощью аннотации @JsonbPropertyOrder. Давайте посмотрим это в действии:
JsonbConfig config
= new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE);
Jsonb jsonb = JsonbBuilder.create(config);
String jsonPerson = jsonb.toJson(person);
Чтобы получить следующее представление JSON:
{
"salary":"1000.0",
"registeredDate":"07-09-2019",
"person-name":"Jhon",
"id":1,
"email":"[email protected]"
}
5.3. Пользовательское сопоставление с адаптерами
Когда нам недостаточно аннотаций и класса JsonbConfig , мы можем использовать адаптеры.
Чтобы их использовать, нам нужно реализовать интерфейс JsonbAdapter , который определяет следующие методы:
-
adaptToJson - С этим методом мы можем использовать собственную логику преобразования
для процесса сериализации.
-
adaptFromJson - Этот метод позволяет нам использовать собственную логику преобразования
для процесса десериализации.
Давайте создадим PersonAdapter для обработки атрибутов id и name класса Person :
public class PersonAdapter implements JsonbAdapter<Person, JsonObject> {
@Override
public JsonObject adaptToJson(Person p) throws Exception {
return Json.createObjectBuilder()
.add("id", p.getId())
.add("name", p.getName())
.build();
}
@Override
public Person adaptFromJson(JsonObject adapted) throws Exception {
Person person = new Person();
person.setId(adapted.getInt("id"));
person.setName(adapted.getString("name"));
return person;
}
}
Кроме того, мы назначим адаптер нашему экземпляру JsonbConfig :
JsonbConfig config = new JsonbConfig().withAdapters(new PersonAdapter());
Jsonb jsonb = JsonbBuilder.create(config);
И мы получим следующее представление JSON:
{
"id":1,
"name":"Jhon"
}
6. Заключение
В этом руководстве мы рассмотрели пример интеграции API JSON-B с приложениями Java с использованием доступных реализаций, а также примеры настройки сериализации и десериализации как во время компиляции, так и во время выполнения.
Полный код доступен, как всегда, over на Github .