Change JSON Field Name with Jackson in Java

Jackson is a very common library for handling JSON and serialization/deserialization in general in Java and Spring Boot based projects.

Jackson handles property names by mapping them as they are to JSON – so propertyName in a POJO will have a corresponding propertyName in JSON. This convention is followed when converting JSON to POJO as well, and if the names don’t match, the conversion can’t be done.

However, there are many cases in which you’d want the serialized JSON properties to have different names, such as standardizing naming conventions for other services (using cases like snake_case, instead of CamelCase) or conflicting property names (a Customer can have a firstName, just as an Agent – and a report may contain both of their firstName properties and needs to be serialized).

Let’s create a Book class, with a few simple fields:

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

Change JSON Field Names with Jackson

When usually converting an instance of a Book into JSON, we’d write the value of the object as a JSON string using ObjectMapper:

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

This results in:

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

The title, author and releaseYear are a 1-to-1 mapping to the title, author and releaseYear fields of the POJO. To change the name of a JSON property and retain it after serialization, there’s no need to change your POJO! It’s enough to annotate the relevant field with @JsonProperty, and supply the JSON name:

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

Now, when we instantiate the object and convert it to JSON:

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

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

The code results in:

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

Change JSON Field Names in JSON-to-POJO Conversion?

It’s worth noting that the name change isn’t one-sided. The same annotation works both ways, and can bridge an incoming JSON with different names into a valid object. For instance, a JSON representing a book with book_title, wouldn’t be mapped to the title property of the Book class by default, as they aren’t the same.

Since we’ve annotated title as book_title – the conversion works just fine:

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

This results in:

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

Note: To construct an object from JSON, your class needs to have an empty constructor as well. Jackson first instantiates the empty object, and then populates the fields using the getters and setters.

Annotate Getters and Setters with @JsonProperty

Do you want to encode different names for serialization and deserialization? For instance, you can serialize Book into a JSON with bt denoting the book’s title, but consume JSON with book_title. You can customize the getters and setters of the Book class with @JsonProperty annotations:

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

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

This way, when serialized, the getBt() method will serialize the title as a bt field in JSON. When reading from JSON (deserializing), you’ll need to supply a book_title, that gets mapped to title.

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Note: Both bt and book_title will be mapped to the title field, but this doesn’t make bt and book_title interchangeable. Jackson won’t be able to convert between them without first converting to title.

Now, you can instantiate a book, serialize it, and deserialize another String into a book with:

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

This results in:

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

Conclusion

In this short tutorial, we’ve taken a look at how Jackson maps object fields to JSON, and how you can change the name of the fields before serialization. We’ve also explored the idea of using different JSON names for serialization and deserialization, using the @JsonProperty annotation on method-level, rather than field-level.

Time Stamp:

More from Stackabuse