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ł odpowiednipropertyName
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ą @JsonProperty
i 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.