Изменить имя поля JSON с помощью Джексона в Java

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 аннотация на уровне метода, а не на уровне поля.

Отметка времени:

Больше от Стекабьюс