Jackson — очень распространенная библиотека для обработки JSON и сериализации/десериализации в целом в проектах на основе Java и Spring Boot.
Джексон обрабатывает имена свойств, сопоставляя их как есть с JSON.
propertyName
в POJO будет иметь соответствующийpropertyName
в JSON. Это соглашение соблюдается и при преобразовании JSON в POJO, и если имена не совпадают, преобразование невозможно.
Однако есть много случаев, когда вы хотели бы, чтобы сериализованные свойства JSON имели разные имена, например, для стандартизации соглашений об именах для других служб (используя такие случаи, как snake_case
, Вместо того, CamelCase
) или конфликтующие имена свойств (a Customer
может иметь firstName
, просто как Agent
– и отчет может содержать оба их firstName
свойства и должны быть сериализованы).
Давайте создадим Book
класс с несколькими простыми полями:
public class Book {
private String title;
private String author;
private int releaseYear;
public Book() {}
public Book(String title, String author, int releaseYear) {
this.title = title;
this.author = author;
this.releaseYear = releaseYear;
}
}
Измените имена полей JSON с помощью Джексона
Обычно при преобразовании экземпляра Book
в JSON, мы запишем значение объекта в виде строки JSON, используя ObjectMapper
:
ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);
Это приводит к:
{"title":"Our Mathematical Universe","author":"Max Tegmark","releaseYear":2014}
Ассоциация title
, author
и releaseYear
представляют собой отображение 1-в-1 на title
, author
и releaseYear
поля POJO. Чтобы изменить имя свойства JSON и сохранить его после сериализации, нет необходимости менять POJO! Достаточно аннотировать соответствующее поле с помощью @JsonProperty
и укажите имя JSON:
public class Book {
@JsonProperty("book_title")
private String title;
@JsonProperty("book_author")
private String author;
@JsonProperty("book_release_year")
private int releaseYear;
public Book(){}
public Book(String title, String author, int releaseYear) {
this.title = title;
this.author = author;
this.releaseYear = releaseYear;
}
}
Теперь, когда мы создаем объект и конвертируем его в JSON:
ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);
Код приводит к:
{"book_title":"Our Mathematical Universe","book_author":"Max Tegmark","book_release_year":2014}
Изменить имена полей JSON при преобразовании JSON в POJO?
Стоит отметить, что смена названия не является односторонней. Одна и та же аннотация работает в обоих направлениях и может соединять входящий JSON с разными именами в допустимый объект. Например, JSON, представляющий книгу с book_title
, не будет сопоставлен с title
собственность Book
class по умолчанию, так как они не совпадают.
Поскольку мы аннотировали title
as book_title
- преобразование работает просто отлично:
Book bookReconstructed = mapper.readValue(jsonBook, Book.class);
System.out.print(bookReconstructed);
Это приводит к:
Book{title='Our Mathematical Universe', author='Max Tegmark', releaseYear=2014}
Примечание: Чтобы построить объект из JSON, ваш класс также должен иметь пустой конструктор. Джексон сначала создает пустой объект, а затем заполняет поля с помощью геттеров и сеттеров.
Аннотируйте геттеры и сеттеры с помощью @JsonProperty
Вы хотите закодировать разные имена для сериализации и десериализации? Например, вы можете сериализовать Book
в JSON с bt
обозначая название книги, но использовать JSON с book_title
. Вы можете настроить геттеры и сеттеры Book
класс с @JsonProperty
аннотации:
@JsonProperty("bt")
public String getBt() {
return title;
}
@JsonProperty("book_title")
public void setTitle(String title) {
this.title = title;
}
Таким образом, при сериализации getBt()
метод сериализует title
как bt
поле в формате JSON. При чтении из JSON (десериализация) вам необходимо указать book_title
, который сопоставляется с title
.
Ознакомьтесь с нашим практическим руководством по изучению Git с рекомендациями, принятыми в отрасли стандартами и прилагаемой памяткой. Перестаньте гуглить команды Git и на самом деле изучить это!
Примечание: Оба формата bt
и book_title
будет сопоставлен с title
поле, но это не делает bt
и book_title
сменный. Джексон не сможет конвертировать между ними без предварительного преобразования в title
.
Теперь вы можете создать экземпляр книги, сериализовать ее и десериализовать другую строку в книгу с помощью:
ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);
String input = "{"author":"Max Tegmark","releaseYear":2017,"book_title":"Life 3.0"}";
Book bookReconstructed = mapper.readValue(input, Book.class);
System.out.print(bookReconstructed);
Это приводит к:
{"author":"Max Tegmark","releaseYear":2014,"bt":"Our Mathematical Universe"}
Book{title='Life 3.0', author='Max Tegmark', releaseYear=2017}
Заключение
В этом кратком руководстве мы рассмотрели, как Джексон сопоставляет поля объекта с JSON и как вы можете изменить имя полей перед сериализацией. Мы также рассмотрели идею использования разных имен JSON для сериализации и десериализации, используя @JsonProperty
аннотация на уровне метода, а не на уровне поля.