Ändra JSON-fältnamn med Jackson i Java

Jackson är ett mycket vanligt bibliotek för att hantera JSON och serialisering/deserialisering i allmänhet i Java- och Spring Boot-baserade projekt.

Jackson hanterar egendomsnamn genom att mappa dem som de är till JSON – alltså propertyName i en POJO kommer att ha en motsvarande propertyName i JSON. Denna konvention följs även när JSON konverteras till POJO, och om namnen inte stämmer överens kan konverteringen inte göras.

Det finns dock många fall där du vill att de serialiserade JSON-egenskaperna ska ha olika namn, till exempel standardisering av namnkonventioner för andra tjänster (med hjälp av fall som snake_case, istället för CamelCase) eller motstridiga egendomsnamn (a Customer kan ha en firstName, precis som en Agent – och en rapport kan innehålla båda firstName egenskaper och måste serialiseras).

Låt oss skapa en Book klass, med några enkla fält:

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

Ändra JSON-fältnamn med Jackson

När man vanligtvis konverterar en instans av en Book i JSON, skulle vi skriva värdet på objektet som en JSON-sträng med hjälp av ObjectMapper:

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

Detta resulterar i:

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

Smakämnen title, author och releaseYear är en 1-till-1-mappning till title, author och releaseYear POJO:s fält. För att ändra namnet på en JSON-egendom och behålla den efter serialisering, behöver du inte ändra din POJO! Det räcker att annotera det relevanta fältet med @JsonProperty, och ange JSON-namnet:

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

Nu, när vi instansierar objektet och konverterar det till JSON:

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

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

Koden resulterar i:

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

Ändra JSON-fältnamn i JSON-till-POJO-konvertering?

Det är värt att notera att namnbytet inte är ensidigt. Samma anteckning fungerar åt båda hållen och kan överbrygga en inkommande JSON med olika namn till ett giltigt objekt. Till exempel en JSON som representerar en bok med book_title, skulle inte mappas till title egendom till Book klass som standard, eftersom de inte är samma.

Sedan vi har kommenterat title as book_title – omvandlingen fungerar bra:

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

Detta resulterar i:

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

Notera: För att konstruera ett objekt från JSON måste din klass också ha en tom konstruktor. Jackson instansierar först det tomma objektet och fyller sedan i fälten med hjälp av getters och setters.

Annotera Getters och Setters med @JsonProperty

Vill du koda olika namn för serialisering och deserialisering? Du kan till exempel serialisera Book till en JSON med bt anger bokens titel, men konsumerar JSON med book_title. Du kan anpassa getters och seters för Book klass med @JsonProperty annoteringar:

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

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

På detta sätt, när den serialiseras, getBt() metoden kommer att serialisera title som en bt fältet i JSON. När du läser från JSON (deserialisering) måste du ange en book_title, som mappas till title.

Kolla in vår praktiska, praktiska guide för att lära dig Git, med bästa praxis, branschaccepterade standarder och medföljande fuskblad. Sluta googla Git-kommandon och faktiskt lära Det!

Notera: Både bt och book_title kommer att mappas till title fältet, men det gör det inte bt och book_title utbytbar. Jackson kommer inte att kunna konvertera mellan dem utan att först konvertera till title.

Nu kan du instansiera en bok, serialisera den och deserialisera en annan sträng till en bok med:

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

Detta resulterar i:

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

Slutsats

I den här korta handledningen har vi tagit en titt på hur Jackson mappar objektfält till JSON, och hur du kan ändra namnet på fälten före serialisering. Vi har också utforskat idén att använda olika JSON-namn för serialisering och deserialisering, med hjälp av @JsonProperty anteckning på metodnivå, snarare än fältnivå.

Tidsstämpel:

Mer från Stackabuse