W3docs

Java JSON avec Gson

Analysez et sérialisez du JSON en Java avec la bibliothèque Gson de Google — toJson, fromJson et TypeToken.

JSON est la lingua franca des API web modernes, et les applications Java doivent constamment transformer des objets en JSON et analyser du JSON pour le reconvertir en objets. Gson est la bibliothèque open-source de Google pour exactement cela : une boîte à outils légère, sans dépendances, qui fait correspondre des objets Java à du texte JSON et inversement, avec presque aucun code répétitif. Ce chapitre montre comment Gson fonctionne et les patterns que vous utiliserez au quotidien.

Si vous débutez avec le format lui-même, commencez par l'introduction à JSON ; pour la bibliothèque alternative principale, consultez Java JSON avec Jackson.

Ajouter Gson à votre projet

Gson ne fait pas partie du JDK, vous devez donc l'ajouter en tant que dépendance. Avec Maven, déclarez-la dans votre pom.xml :

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.11.0</version>
</dependency>

Avec Gradle, la même dépendance tient en une seule ligne :

implementation 'com.google.code.gson:gson:2.11.0'

Tout ce que vous faites avec Gson passe par une seule classe point d'entrée, Gson. Vous créez généralement une instance et la réutilisez — elle est thread-safe et peu coûteuse à partager.

import com.google.gson.Gson;

Gson gson = new Gson();

Sérialiser des objets en JSON

Transformer un objet Java en texte JSON s'appelle la sérialisation, et Gson le fait avec toJson(). Vous lui passez n'importe quel objet et Gson parcourt ses champs par réflexion, produisant une chaîne JSON. Aucune annotation ni configuration n'est requise pour les classes ordinaires.

class Book {
    String title;
    String author;
    int year;
    boolean inStock;

    Book(String title, String author, int year, boolean inStock) {
        this.title = title;
        this.author = author;
        this.year = year;
        this.inStock = inStock;
    }
}

Gson gson = new Gson();
Book b = new Book("Clean Code", "Robert Martin", 2008, true);
String json = gson.toJson(b);
// {"title":"Clean Code","author":"Robert Martin","year":2008,"inStock":true}

Les noms de champs deviennent des clés JSON, et les types Java correspondent aux types JSON naturels : String vers une chaîne entre guillemets, int/double vers un nombre, boolean vers true/false. Un champ null est omis par défaut.

Désérialiser du JSON en objets

La direction inverse — la désérialisation — utilise fromJson(). Vous passez le texte JSON et la Class cible, et Gson crée une instance et remplit les champs en faisant correspondre les clés JSON aux noms de champs.

String json = "{\"title\":\"Clean Code\",\"author\":\"Robert Martin\",\"year\":2008,\"inStock\":true}";

Gson gson = new Gson();
Book b = gson.fromJson(json, Book.class);

System.out.println(b.title);  // Clean Code
System.out.println(b.year);   // 2008

Si une clé JSON n'a pas de champ correspondant, Gson l'ignore ; si un champ n'a pas de clé correspondante, il conserve sa valeur par défaut (null, 0 ou false). Ce comportement tolérant rend Gson robuste lorsqu'une API ajoute de nouveaux champs.

TypeToken pour les collections génériques

En raison de l'effacement de type, Java supprime les informations de type générique à l'exécution, donc gson.fromJson(json, List.class) ne peut pas savoir que vous voulez une List<Book> — il retournerait une List d'objets LinkedTreeMap. Gson résout ce problème avec TypeToken, qui capture le type générique complet afin que la désérialisation produise les éléments attendus.

import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;

String json = "[{\"title\":\"Effective Java\",\"year\":2018}]";

Type listType = new TypeToken<List<Book>>(){}.getType();
List<Book> books = gson.fromJson(json, listType);

Utilisez un TypeToken chaque fois que le type cible implique des génériques — List<T>, Map<K, V>, ou des combinaisons imbriquées. Pour les classes simples non génériques, la forme Book.class suffit.

Pretty printing et configuration personnalisée

Le Gson par défaut produit un JSON compact sur une seule ligne. Pour configurer le comportement, vous construisez une instance avec GsonBuilder. La demande la plus courante est le pretty printing — une sortie lisible et indentée pour les journaux et les fichiers de configuration.

import com.google.gson.GsonBuilder;

Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .serializeNulls()        // include null fields instead of dropping them
        .create();

System.out.println(gson.toJson(b));

GsonBuilder contrôle de nombreux autres comportements. Voici quelques-uns que vous rencontrerez souvent :

Méthode du builderEffet
setPrettyPrinting()Sortie indentée sur plusieurs lignes
serializeNulls()Émet les champs null au lieu de les ignorer
setDateFormat(...)Contrôle la mise en forme des valeurs Date
registerTypeAdapter(...)Branche un sérialiseur/désérialiseur personnalisé pour un type
excludeFieldsWithoutExposeAnnotation()Sérialise uniquement les champs annotés @Expose

Pour un contrôle total sur un type, vous enregistrez un adaptateur personnalisé implémentant JsonSerializer et/ou JsonDeserializer — utile quand un champ nécessite une mise en forme spéciale que la réflexion ne peut pas déduire.

Exemple complet : sérialisation, analyse et aller-retour

Gson lui-même n'est pas dans le classpath de ce runner, donc le programme ci-dessous démontre les mêmes concepts en utilisant uniquement le JDK : il sérialise un enregistrement en JSON à la main, analyse le texte pour le reconvertir en champs, reconstruit l'objet et confirme que l'aller-retour est sans perte. C'est exactement ce que gson.toJson() et gson.fromJson() automatisent pour vous.

java— editable, runs on the server

Ce qu'il faut retenir de l'exécution :

  • La première ligne montre la sérialisation : l'enregistrement Book devient {"title":"Clean Code","author":"Robert Martin","year":2008,"inStock":true}, où chaque champ est une clé JSON et les types correspondent à leurs formes JSON naturelles — exactement ce que gson.toJson() produit.
  • La deuxième ligne montre la désérialisation : analyser ce texte et reconstruire un Book, le même travail que gson.fromJson(json, Book.class) effectue en un seul appel.
  • Round-trip equal? true prouve que la conversion est sans perte — sérialiser puis désérialiser produit un objet égal à l'original, la propriété que tout mappeur JSON vise.
  • La ligne Array JSON montre une List<Book> rendue sous forme de tableau JSON d'objets, la structure que vous désérialiseriez avec un TypeToken<List<Book>>.
  • Le bloc Pretty montre une sortie indentée sur plusieurs lignes, illustrant ce que GsonBuilder.setPrettyPrinting() vous offre par rapport au format compact par défaut.

Exercice

Pratique
Dans Gson, pourquoi faut-il un TypeToken pour désérialiser une List<Book> plutôt que de simplement passer List.class ?
Dans Gson, pourquoi faut-il un TypeToken pour désérialiser une List<Book> plutôt que de simplement passer List.class ?
Was this page helpful?