Jackson es una biblioteca muy común para manejar JSON y serialización/deserialización en general en proyectos basados en Java y Spring Boot.
Jackson maneja los nombres de las propiedades asignándolos tal como son a JSON, por lo que
propertyName
en un POJO tendrá un correspondientepropertyName
en JSON. Esta convención también se sigue al convertir JSON a POJO, y si los nombres no coinciden, no se puede realizar la conversión.
Sin embargo, hay muchos casos en los que le gustaría que las propiedades JSON serializadas tuvieran nombres diferentes, como estandarizar las convenciones de nomenclatura para otros servicios (usando casos como snake_case
, En lugar de CamelCase
) o nombres de propiedades en conflicto (una Customer
puede tener una firstName
, solo como un Agent
– y un informe puede contener ambos firstName
propiedades y necesita ser serializado).
Vamos a crear un Book
clase, con unos pocos 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;
}
}
Cambiar nombres de campo JSON con Jackson
Cuando normalmente se convierte una instancia de un Book
en JSON, escribiríamos el valor del objeto como una cadena 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);
Esto resulta en:
{"title":"Our Mathematical Universe","author":"Max Tegmark","releaseYear":2014}
El title
, author
y releaseYear
son un mapeo 1 a 1 para el title
, author
y releaseYear
campos del POJO. Para cambiar el nombre de una propiedad JSON y conservarla después de la serialización, ¡no es necesario cambiar su POJO! Es suficiente anotar el campo relevante con @JsonProperty
y proporcione el nombre 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;
}
}
Ahora, cuando instanciamos el objeto y lo convertimos a JSON:
ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);
El código da como resultado:
{"book_title":"Our Mathematical Universe","book_author":"Max Tegmark","book_release_year":2014}
¿Cambiar los nombres de campo JSON en la conversión de JSON a POJO?
Vale la pena señalar que el cambio de nombre no es unilateral. La misma anotación funciona en ambos sentidos y puede unir un JSON entrante con diferentes nombres en un objeto válido. Por ejemplo, un JSON que representa un libro con book_title
, no se asignaría a la title
propiedad de la Book
class por defecto, ya que no son lo mismo.
Ya que hemos anotado title
as book_title
– la conversión funciona bien:
Book bookReconstructed = mapper.readValue(jsonBook, Book.class);
System.out.print(bookReconstructed);
Esto resulta en:
Book{title='Our Mathematical Universe', author='Max Tegmark', releaseYear=2014}
Nota: Para construir un objeto desde JSON, su clase también debe tener un constructor vacío. Jackson primero crea una instancia del objeto vacío y luego llena los campos utilizando los getters y setters.
Anotar Getters y Setters con @JsonProperty
¿Desea codificar diferentes nombres para serialización y deserialización? Por ejemplo, puede serializar Book
en un JSON con bt
que indica el título del libro, pero consume JSON con book_title
. Puede personalizar los getters y setters del Book
clase con @JsonProperty
anotaciones:
@JsonProperty("bt")
public String getBt() {
return title;
}
@JsonProperty("book_title")
public void setTitle(String title) {
this.title = title;
}
De esta forma, al ser serializado, el getBt()
El método serializará el title
como herramienta de edición del bt
campo en JSON. Al leer desde JSON (deserializar), deberá proporcionar un book_title
, que se asigna a title
.
Consulte nuestra guía práctica y práctica para aprender Git, con las mejores prácticas, los estándares aceptados por la industria y la hoja de trucos incluida. Deja de buscar en Google los comandos de Git y, de hecho, aprenden ella!
Nota: Ambos bt
y book_title
será mapeado a la title
campo, pero esto no hace bt
y book_title
intercambiable. Jackson no podrá convertir entre ellos sin convertir primero a title
.
Ahora, puede crear una instancia de un libro, serializarlo y deserializar otra cadena en un libro con:
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);
Esto resulta en:
{"author":"Max Tegmark","releaseYear":2014,"bt":"Our Mathematical Universe"}
Book{title='Life 3.0', author='Max Tegmark', releaseYear=2017}
Conclusión
En este breve tutorial, hemos analizado cómo Jackson asigna campos de objetos a JSON y cómo puede cambiar el nombre de los campos antes de la serialización. También exploramos la idea de usar diferentes nombres JSON para serialización y deserialización, usando el @JsonProperty
anotación a nivel de método, en lugar de a nivel de campo.