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 correspondentepropertyName
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.