Changer le nom du champ JSON avec Jackson en Java

Jackson est une bibliothèque très courante pour gérer JSON et la sérialisation/désérialisation en général dans les projets basés sur Java et Spring Boot.

Jackson gère les noms de propriété en les mappant tels qu'ils sont à JSON - donc propertyName dans un POJO aura un correspondant propertyName en JSON. Cette convention est également suivie lors de la conversion de JSON en POJO, et si les noms ne correspondent pas, la conversion ne peut pas être effectuée.

Cependant, il existe de nombreux cas dans lesquels vous voudriez que les propriétés JSON sérialisées aient des noms différents, comme la normalisation des conventions de dénomination pour d'autres services (en utilisant des cas comme snake_case, Au lieu d' CamelCase) ou des noms de propriété en conflit (un Customer peut avoir un firstName, tout comme un Agent – et un rapport peut contenir à la fois leurs firstName propriétés et doit être sérialisé).

Créons un Book classe, avec quelques champs 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;
    }
    
}

Changer les noms de champs JSON avec Jackson

Lors de la conversion habituelle d'une instance d'un Book dans JSON, nous écrirons la valeur de l'objet sous la forme d'une chaîne JSON en utilisant ObjectMapper:

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

Cela se traduit par:

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

La title, author ainsi que releaseYear sont un mappage 1-à-1 vers le title, author ainsi que releaseYear champs du POJO. Pour changer le nom d'une propriété JSON et la conserver après sérialisation, inutile de changer votre POJO ! Il suffit d'annoter le champ concerné avec @JsonProperty, et indiquez le nom 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;
    }
    
}

Maintenant, lorsque nous instancions l'objet et le convertissons en JSON :

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

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

Le code donne :

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

Modifier les noms de champ JSON dans la conversion JSON en POJO ?

Il convient de noter que le changement de nom n'est pas unilatéral. La même annotation fonctionne dans les deux sens et peut relier un JSON entrant avec des noms différents dans un objet valide. Par exemple, un JSON représentant un livre avec book_title, ne serait pas mappé au title propriété du Book classe par défaut, car ils ne sont pas identiques.

Depuis que nous avons annoté title as book_title – la conversion fonctionne très bien :

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

Cela se traduit par:

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

Remarque: Pour construire un objet à partir de JSON, votre classe doit également avoir un constructeur vide. Jackson instancie d'abord l'objet vide, puis remplit les champs à l'aide des getters et des setters.

Annotez les getters et les setters avec @JsonProperty

Voulez-vous encoder des noms différents pour la sérialisation et la désérialisation ? Par exemple, vous pouvez sérialiser Book dans un JSON avec bt indiquant le titre du livre, mais consommez JSON avec book_title. Vous pouvez personnaliser les getters et les setters du Book classe avec @JsonProperty annotations :

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

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

De cette façon, une fois sérialisé, le getBt() méthode va sérialiser le title en tant que bt champ dans JSON. Lors de la lecture à partir de JSON (désérialisation), vous devrez fournir un book_title, qui est mappé à title.

Consultez notre guide pratique et pratique pour apprendre Git, avec les meilleures pratiques, les normes acceptées par l'industrie et la feuille de triche incluse. Arrêtez de googler les commandes Git et en fait apprendre il!

Remarque: Les deux bt ainsi que book_title sera mappé sur le title champ, mais cela ne fait pas bt ainsi que book_title interchangeable. Jackson ne pourra pas convertir entre eux sans d'abord convertir en title.

Maintenant, vous pouvez instancier un livre, le sérialiser et désérialiser une autre chaîne dans un livre avec :

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

Cela se traduit par:

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

Conclusion

Dans ce court didacticiel, nous avons examiné comment Jackson mappe les champs d'objets sur JSON et comment vous pouvez modifier le nom des champs avant la sérialisation. Nous avons également exploré l'idée d'utiliser différents noms JSON pour la sérialisation et la désérialisation, en utilisant le @JsonProperty annotation au niveau de la méthode plutôt qu'au niveau du champ.

Horodatage:

Plus de Stackabuse