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