Introduction à l’API de liaison JSON (JSR 367) en Java

1. Vue d’ensemble

Pendant longtemps, il n’y avait pas de norme pour le traitement JSON en Java. Les bibliothèques les plus couramment utilisées pour le traitement JSON sont Jackson et Gson.

Récemment, Java EE7 est venu avec une API pour analyser et générer du JSON ( JSR 353: API Java pour le traitement JSON .

Enfin, avec la sortie de JEE 8, il existe une API normalisée ( JSR 367: API Java pour la liaison JSON (JSON-B) .

Pour l’instant, ses principales implémentations sont Eclipse Yasson (RI) et Apache Johnzon .

2. API JSON-B

2.1. Dépendance Maven

Commençons par ajouter la dépendance nécessaire.

Gardez à l’esprit que dans de nombreux cas, il suffira d’inclure la dépendance pour l’implémentation choisie et le javax.json.bind-api sera inclus de manière transitoire:

<dependency>
    <groupId>javax.json.bind</groupId>
    <artifactId>javax.json.bind-api</artifactId>
    <version>1.0</version>
</dependency>

La version la plus récente est disponible sur Maven Central .

3. Utilisation d’Eclipse Yasson

  • Eclipse Yasson est l’implémentation de référence officielle ** de l’API JSON Binding ( JSR-367 ).

3.1. Dépendance Maven

Pour l’utiliser, nous devons inclure les dépendances suivantes dans notre projet Maven:

<dependency>
    <groupId>org.eclipse</groupId>
    <artifactId>yasson</artifactId>
    <version>1.0.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.json</artifactId>
    <version>1.1.2</version>
</dependency>

Les versions les plus récentes sont disponibles à l’adresse Maven Central.

4. Utiliser Apache Johnzon

Apache Johnzon est une autre implémentation compatible avec les API JSON-P (JSR-353) et JSON-B (JSR-367).

4.1. Dépendance Maven

Pour l’utiliser, nous devons inclure les dépendances suivantes dans notre projet Maven:

<dependency>
    <groupId>org.apache.geronimo.specs</groupId>
    <artifactId>geronimo-json__1.1__spec</artifactId>
    <version>1.0</version>
</dependency>
<dependency>
    <groupId>org.apache.johnzon</groupId>
    <artifactId>johnzon-jsonb</artifactId>
    <version>1.1.4</version>
</dependency>

Les versions les plus récentes sont disponibles à l’adresse Maven Central.

5. Fonctionnalités de l’API

L’API fournit des annotations pour personnaliser la sérialisation/désérialisation.

Créons une classe simple et voyons comment se présente l’exemple de configuration:

public class Person {

    private int id;

    @JsonbProperty("person-name")
    private String name;

    @JsonbProperty(nillable = true)
    private String email;

    @JsonbTransient
    private int age;

    @JsonbDateFormat("dd-MM-yyyy")
    private LocalDate registeredDate;

    private BigDecimal salary;

    @JsonbNumberFormat(locale = "en__US", value = "#0.0")
    public BigDecimal getSalary() {
        return salary;
    }

   //standard getters and setters
}

Après la sérialisation, un objet de cette classe ressemblera à:

{
   "email":"[email protected]",
   "id":1,
   "person-name":"Jhon",
   "registeredDate":"07-09-2019",
   "salary":"1000.0"
}

Les annotations utilisées ici sont:

  • @ JsonbProperty - utilisé pour spécifier un nom de champ personnalisé

  • @ JsonbTransient - lorsque nous voulons ignorer le champ pendant

désérialisation/sérialisation ** @ JsonbDateFormat - lorsque nous voulons définir le format d’affichage du

rendez-vous amoureux ** @ JsonbNumberFormat - pour spécifier le format d’affichage pour numérique

valeurs ** @ JsonbNillable - pour activer la sérialisation des valeurs NULL

5.1. Sérialisation et désérialisation

Tout d’abord, pour obtenir la représentation JSON de notre objet, nous devons utiliser la classe JsonbBuilder et sa méthode toJson () .

Pour commencer, créons un objet simple Person comme ceci:

Person person = new Person(
  1,
  "Jhon",
  "[email protected]",
  20,
  LocalDate.of(2019, 9, 7),
  BigDecimal.valueOf(1000));

Et instancier la classe Jsonb :

Jsonb jsonb = JsonbBuilder.create();

Ensuite, nous utilisons la méthode toJson :

String jsonPerson = jsonb.toJson(person);

Pour obtenir la représentation JSON suivante:

{
    "email":"[email protected]",
    "id":1,
    "person-name":"Jhon",
    "registeredDate":"07-09-2019",
    "salary":"1000.0"
}

Si nous voulons faire la conversion dans l’autre sens, nous pouvons utiliser la méthode fromJson :

Person person = jsonb.fromJson(jsonPerson, Person.class);

Naturellement, nous pouvons également traiter des collections:

List<Person> personList = Arrays.asList(...);
String jsonArrayPerson = jsonb.toJson(personList);

Pour obtenir la représentation JSON suivante:

----[
    {
      "email":"[email protected]",
      "id":1,
      "person-name":"Jhon",
      "registeredDate":"09-09-2019",
      "salary":"1000.0"
    },
    {
      "email":"[email protected]",
      "id":2,
      "person-name":"Jhon",
      "registeredDate":"09-09-2019",
      "salary":"1500.0"
    },
    ...]----

Pour convertir un tableau JSON en List , nous allons utiliser l’API fromJson :

List<Person> personList = jsonb.fromJson(
  personJsonArray,
  new ArrayList<Person>(){}.getClass().getGenericSuperclass()
);

5.2. Mappage personnalisé avec JsonbConfig

La classe JsonbConfig nous permet de personnaliser le processus de mappage pour toutes les classes.

Par exemple, nous pouvons modifier les stratégies de dénomination par défaut ou l’ordre des propriétés.

Nous allons maintenant utiliser la stratégie LOWER CASE WITH UNDERSCORES__:

JsonbConfig config = new JsonbConfig().withPropertyNamingStrategy(
  PropertyNamingStrategy.LOWER__CASE__WITH__UNDERSCORES);
Jsonb jsonb = JsonbBuilder.create(config);
String jsonPerson = jsonb.toJson(person);

Pour obtenir la représentation JSON suivante:

{
   "email":"[email protected]",
   "id":1,
   "person-name":"Jhon",
   "registered__date":"07-09-2019",
   "salary":"1000.0"
}

Nous allons maintenant modifier l’ordre des propriétés avec la stratégie REVERSE . En utilisant cette stratégie, l’ordre des propriétés est inversé par rapport à l’ordre lexicographique. Cela peut également être configuré à la compilation avec l’annotation @JsonbPropertyOrder. Voyons cela en action:

JsonbConfig config
  = new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE);
Jsonb jsonb = JsonbBuilder.create(config);
String jsonPerson = jsonb.toJson(person);

Pour obtenir la représentation JSON suivante:

{
    "salary":"1000.0",
    "registeredDate":"07-09-2019",
    "person-name":"Jhon",
    "id":1,
    "email":"[email protected]"
}

5.3. Cartographie personnalisée avec des adaptateurs

Lorsque les annotations et la classe JsonbConfig ne nous suffisent pas, nous pouvons utiliser des adaptateurs.

Pour les utiliser, nous devons implémenter l’interface JsonbAdapter , qui définit les méthodes suivantes:

  • adaptToJson - Avec cette méthode, nous pouvons utiliser une logique de conversion personnalisée

pour le processus de sérialisation.

  • adaptFromJson - Cette méthode nous permet d’utiliser une logique de conversion personnalisée

pour le processus de désérialisation.

Créons un PersonAdapter pour traiter les attributs id et name de la classe Person :

public class PersonAdapter implements JsonbAdapter<Person, JsonObject> {

    @Override
    public JsonObject adaptToJson(Person p) throws Exception {
        return Json.createObjectBuilder()
          .add("id", p.getId())
          .add("name", p.getName())
          .build();
    }

    @Override
    public Person adaptFromJson(JsonObject adapted) throws Exception {
        Person person = new Person();
        person.setId(adapted.getInt("id"));
        person.setName(adapted.getString("name"));
        return person;
    }
}

De plus, nous assignerons l’adaptateur à notre instance JsonbConfig :

JsonbConfig config = new JsonbConfig().withAdapters(new PersonAdapter());
Jsonb jsonb = JsonbBuilder.create(config);

Et nous obtiendrons la représentation JSON suivante:

{
    "id":1,
    "name":"Jhon"
}

6. Conclusion

Dans ce didacticiel, nous avons vu comment intégrer l’API JSON-B aux applications Java à l’aide des implémentations disponibles, ainsi que des exemples de personnalisation de la sérialisation et de la désérialisation à la compilation et à l’exécution.

Le code complet est disponible, comme toujours, over sur Github .