Cambiar el nombre del campo JSON con Jackson en Java

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 correspondiente propertyName 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 @JsonPropertyy 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.

Sello de tiempo:

Mas de Abuso de pila