Alterar o nome do campo JSON com Jackson em Java

Jackson é uma biblioteca muito comum para lidar com JSON e serialização/desserialização em geral em projetos baseados em Java e Spring Boot.

Jackson lida com nomes de propriedades mapeando-os como eles são para JSON – então propertyName em um POJO terá um correspondente propertyName em JSON. Essa convenção também é seguida ao converter JSON para POJO e, se os nomes não corresponderem, a conversão não poderá ser feita.

No entanto, há muitos casos em que você deseja que as propriedades JSON serializadas tenham nomes diferentes, como padronizar convenções de nomenclatura para outros serviços (usando casos como snake_case, ao invés de CamelCase) ou nomes de propriedade conflitantes (um Customer pode ter um firstName, apenas como um Agent – e um relatório pode conter ambos os seus firstName propriedades e precisa ser serializado).

Vamos criar um Book class, com alguns campos simples:

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

Alterar nomes de campo JSON com Jackson

Ao converter normalmente uma instância de um Book em JSON, escreveríamos o valor do objeto como uma string JSON usando ObjectMapper:

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

Isto resulta em:

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

A title, author e releaseYear são um mapeamento de 1 para 1 para o title, author e releaseYear campos do POJO. Para alterar o nome de uma propriedade JSON e mantê-la após a serialização, não há necessidade de alterar seu POJO! Basta anotar o campo relevante com @JsonProperty, e forneça o nome 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;
    }
    
}

Agora, quando instanciamos o objeto e o convertemos para JSON:

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

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

O código resulta em:

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

Alterar nomes de campo JSON na conversão JSON para POJO?

Vale a pena notar que a mudança de nome não é unilateral. A mesma anotação funciona nos dois sentidos e pode conectar um JSON de entrada com nomes diferentes em um objeto válido. Por exemplo, um JSON representando um livro com book_title, não seria mapeado para o title propriedade do Book class por padrão, pois eles não são os mesmos.

Desde que anotamos title as book_title – a conversão funciona bem:

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

Isto resulta em:

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

Observação: Para construir um objeto a partir de JSON, sua classe também precisa ter um construtor vazio. Jackson primeiro instancia o objeto vazio e, em seguida, preenche os campos usando os getters e setters.

Anote Getters e Setters com @JsonProperty

Deseja codificar nomes diferentes para serialização e desserialização? Por exemplo, você pode serializar Book em um JSON com bt denotando o título do livro, mas consuma JSON com book_title. Você pode personalizar os getters e setters do Book aula com @JsonProperty anotações:

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

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

Desta forma, quando serializado, o getBt() método irá serializar o title como um bt campo em JSON. Ao ler do JSON (desserializando), você precisará fornecer um book_title, que é mapeado para title.

Confira nosso guia prático e prático para aprender Git, com práticas recomendadas, padrões aceitos pelo setor e folha de dicas incluída. Pare de pesquisar comandos Git no Google e realmente aprender -lo!

Observação: Ambos bt e book_title será mapeado para o title campo, mas isso não faz bt e book_title intercambiável. Jackson não poderá converter entre eles sem primeiro converter para title.

Agora, você pode instanciar um livro, serializá-lo e desserializar outro String em um livro com:

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

Isto resulta em:

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

Conclusão

Neste breve tutorial, vimos como Jackson mapeia campos de objeto para JSON e como você pode alterar o nome dos campos antes da serialização. Também exploramos a ideia de usar nomes JSON diferentes para serialização e desserialização, usando o @JsonProperty anotação em nível de método, em vez de nível de campo.

Carimbo de hora:

Mais de Abuso de pilha