Zmień nazwę pola JSON na Jacksona w Javie

Jackson jest bardzo powszechną biblioteką do obsługi JSON i ogólnie serializacji/deserializacji w projektach opartych na Java i Spring Boot.

Jackson obsługuje nazwy właściwości, mapując je do formatu JSON — więc propertyName w POJO będzie miał odpowiedni propertyName w formacie JSON. Ta konwencja jest również przestrzegana podczas konwersji JSON na POJO, a jeśli nazwy się nie zgadzają, nie można wykonać konwersji.

Istnieje jednak wiele przypadków, w których serializowane właściwości JSON powinny mieć różne nazwy, takie jak standaryzacja konwencji nazewnictwa dla innych usług (przy użyciu przypadków takich jak snake_case, zamiast CamelCase) lub sprzeczne nazwy właściwości (a Customer może mieć firstName, tak jak i Agent – a raport może zawierać oba z nich firstName właściwości i musi być serializowany).

Stwórzmy plik Book klasa, z kilkoma prostymi polami:

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;
    }
    
}

Zmień nazwy pól JSON za pomocą Jacksona

Kiedy zwykle konwertujesz instancję a Book do JSON, zapisalibyśmy wartość obiektu jako ciąg JSON za pomocą ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
        
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);

To skutkuje:

{"title":"Our Mathematical Universe","author":"Max Tegmark","releaseYear":2014}

Połączenia title, author i releaseYear są mapowaniem 1-do-1 do title, author i releaseYear pola POJO. Aby zmienić nazwę właściwości JSON i zachować ją po serializacji, nie trzeba zmieniać POJO! Wystarczy opisać odpowiednie pole za pomocą @JsonPropertyi podaj nazwę 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;
    }
    
}

Teraz, gdy tworzymy instancję obiektu i konwertujemy go na JSON:

ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);

String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);

Kod skutkuje:

{"book_title":"Our Mathematical Universe","book_author":"Max Tegmark","book_release_year":2014}

Zmienić nazwy pól JSON w konwersji JSON na POJO?

Warto zauważyć, że zmiana nazwy nie jest jednostronna. Ta sama adnotacja działa w obie strony i może połączyć przychodzący plik JSON o różnych nazwach z prawidłowym obiektem. Na przykład JSON reprezentujący książkę z book_title, nie zostanie zmapowany do title właściwość Book klasy domyślnie, ponieważ nie są takie same.

Odkąd dodaliśmy adnotacje title as book_title – konwersja działa dobrze:

Book bookReconstructed = mapper.readValue(jsonBook, Book.class);
System.out.print(bookReconstructed);

To skutkuje:

Book{title='Our Mathematical Universe', author='Max Tegmark', releaseYear=2014}

Uwaga: Aby skonstruować obiekt z JSON, twoja klasa również musi mieć pusty konstruktor. Jackson najpierw tworzy instancję pustego obiektu, a następnie wypełnia pola za pomocą metod pobierających i ustawiających.

Opisywanie getterów i seterów za pomocą @JsonProperty

Czy chcesz zakodować różne nazwy dla serializacji i deserializacji? Na przykład możesz serializować Book do JSON z bt oznaczające tytuł książki, ale używaj JSON z book_title. Możesz dostosować pobierające i ustawiające Book klasa z @JsonProperty adnotacje:

@JsonProperty("bt")
public String getBt() {
    return title;
}

@JsonProperty("book_title")
public void setTitle(String title) {
    this.title = title;
}

W ten sposób, po serializacji, getBt() metoda zserializuje title jak bt pole w formacie JSON. Podczas czytania z JSON (deserializacji) musisz podać a book_title, który jest mapowany do title.

Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!

Uwaga: Obie bt i book_title zostanie zmapowany do title pole, ale to nie czyni bt i book_title wymienny. Jackson nie będzie w stanie dokonać konwersji między nimi bez uprzedniej konwersji do title.

Teraz możesz utworzyć instancję książki, zserializować ją i zdeserializować inny ciąg do książki za pomocą:

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);

To skutkuje:

{"author":"Max Tegmark","releaseYear":2014,"bt":"Our Mathematical Universe"}
Book{title='Life 3.0', author='Max Tegmark', releaseYear=2017}

Wnioski

W tym krótkim samouczku przyjrzeliśmy się, jak Jackson mapuje pola obiektów do formatu JSON i jak można zmienić nazwy pól przed serializacją. Zbadaliśmy również pomysł używania różnych nazw JSON do serializacji i deserializacji, używając @JsonProperty adnotacja na poziomie metody, a nie na poziomie pola.

Znak czasu:

Więcej z Nadużycie stosu