Manipuler JSON en Java : Guide Complet JSONObject, JSONArray et Gson

Apprenez a manipuler JSON en Java avec JSONObject, JSONArray et Gson. Creez, parcourez et convertissez vos donnees JSON efficacement avec des exemples pratiques et bonnes pratiques.

Mahmoud DEVO
Mahmoud DEVO
December 27, 2025 7 min read
Manipuler JSON en Java : Guide Complet JSONObject, JSONArray et Gson

Introduction

Le format JSON (JavaScript Object Notation) est devenu le standard incontournable pour l’echange de donnees entre applications modernes. Que ce soit pour communiquer avec des APIs REST, stocker des configurations, ou echanger des donnees entre microservices, la maitrise de JSON en Java est une competence essentielle pour tout developpeur.

Dans l’ecosysteme Java, plusieurs bibliotheques permettent de manipuler le JSON de maniere efficace. Les plus populaires sont :

  • org.json : La bibliotheque standard avec JSONObject et JSONArray
  • Gson : La bibliotheque developpee par Google, particulierement puissante pour la serialisation/deserialisation
  • Jackson : Une alternative performante tres utilisee dans les projets Spring

Cet article se concentre sur les deux premieres approches et vous guidera a travers des exemples concrets pour maitriser la manipulation JSON en Java.

Dependances Maven necessaires

Avant de commencer, ajoutez ces dependances a votre fichier pom.xml :

<!-- Bibliotheque org.json -->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20231013</version>
</dependency>

<!-- Bibliotheque Gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Creer un objet JSON avec JSONObject

La classe JSONObject de la bibliotheque org.json permet de creer et manipuler des objets JSON de maniere intuitive.

Creation basique

Pour commencer, vous pouvez creer un objet JSONObject vide en utilisant le constructeur par defaut, puis ajouter des proprietes avec la methode put() :

import org.json.JSONObject;

public class JsonCreation {
    public static void main(String[] args) {
        JSONObject obj = new JSONObject();
        obj.put("nom", "Nikita");
        obj.put("age", 30);
        obj.put("estMarie", true);
        obj.put("salaire", 55000.50);

        System.out.println(obj.toString(2)); // Formatage avec indentation
    }
}

Resultat :

{
  "nom": "Nikita",
  "age": 30,
  "estMarie": true,
  "salaire": 55000.5
}

Methodes de chainage (Fluent API)

Une approche plus elegante consiste a utiliser le chainage de methodes, car put() retourne l’objet JSONObject lui-meme :

JSONObject obj = new JSONObject()
    .put("nom", "Nikita")
    .put("age", 30)
    .put("estMarie", true)
    .put("competences", new JSONArray()
        .put("Java")
        .put("Python")
        .put("SQL"));

System.out.println(obj.toString(2));

Creation a partir d’une Map

Vous pouvez egalement creer un JSONObject directement a partir d’une Map Java :

Map<String, Object> donnees = new HashMap<>();
donnees.put("nom", "Marie");
donnees.put("age", 28);
donnees.put("ville", "Paris");

JSONObject obj = new JSONObject(donnees);
System.out.println(obj.toString());

Creation a partir d’une chaine JSON

Pour parser une chaine JSON existante :

String jsonString = "{\"nom\":\"Pierre\",\"age\":35,\"actif\":true}";
JSONObject obj = new JSONObject(jsonString);

System.out.println("Nom: " + obj.getString("nom"));
System.out.println("Age: " + obj.getInt("age"));

Manipuler et acceder aux donnees JSON

Methodes d’acces aux proprietes

La classe JSONObject offre plusieurs methodes pour acceder aux valeurs :

JSONObject obj = new JSONObject()
    .put("nom", "Alice")
    .put("age", 25)
    .put("actif", true)
    .put("score", 98.5);

// Methodes typees - lancent une exception si la cle n'existe pas
String nom = obj.getString("nom");       // "Alice"
int age = obj.getInt("age");             // 25
boolean actif = obj.getBoolean("actif"); // true
double score = obj.getDouble("score");   // 98.5

// Methode generique
Object valeur = obj.get("nom");          // Retourne Object

Verifier l’existence d’une cle

Avant d’acceder a une propriete, il est recommande de verifier son existence :

if (obj.has("email")) {
    String email = obj.getString("email");
} else {
    System.out.println("Email non defini");
}

Modifier et supprimer des proprietes

// Modifier une valeur existante
obj.put("age", 26);

// Supprimer une propriete
obj.remove("score");

// Verifier si l'objet est vide
boolean estVide = obj.isEmpty();

Gestion des erreurs et exceptions

La manipulation JSON peut generer plusieurs types d’exceptions qu’il faut gerer correctement :

import org.json.JSONException;

public class JsonErrorHandling {
    public static void main(String[] args) {
        String jsonInvalide = "{nom: invalide}"; // JSON mal forme

        try {
            JSONObject obj = new JSONObject(jsonInvalide);
        } catch (JSONException e) {
            System.err.println("Erreur de parsing JSON: " + e.getMessage());
        }

        // Acces a une cle inexistante
        JSONObject obj = new JSONObject().put("nom", "Test");
        try {
            String email = obj.getString("email"); // Cle inexistante
        } catch (JSONException e) {
            System.err.println("Cle non trouvee: " + e.getMessage());
        }
    }
}

## Utilisation de la bibliotheque Gson

Gson est une bibliotheque developpee par Google qui permet une serialisation/deserialisation elegante entre objets Java et JSON.

### Serialisation : Objet Java vers JSON

```java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Personne {
    private String nom;
    private int age;
    private String email;
    private boolean actif;

    public Personne(String nom, int age, String email) {
        this.nom = nom;
        this.age = age;
        this.email = email;
        this.actif = true;
    }

    // Getters et setters...
}

public class GsonExample {
    public static void main(String[] args) {
        Personne personne = new Personne("Jean", 30, "jean@example.com");

        // Gson simple
        Gson gson = new Gson();
        String json = gson.toJson(personne);
        System.out.println(json);
        // {"nom":"Jean","age":30,"email":"jean@example.com","actif":true}

        // Gson avec formatage
        Gson gsonPretty = new GsonBuilder().setPrettyPrinting().create();
        System.out.println(gsonPretty.toJson(personne));
    }
}

Deserialisation : JSON vers Objet Java

String json = "{\"nom\":\"Marie\",\"age\":28,\"email\":\"marie@example.com\",\"actif\":true}";

Gson gson = new Gson();
Personne personne = gson.fromJson(json, Personne.class);

System.out.println("Nom: " + personne.getNom());    // Marie
System.out.println("Age: " + personne.getAge());    // 28

Travailler avec des listes

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

String jsonArray = "[{\"nom\":\"Alice\",\"age\":25},{\"nom\":\"Bob\",\"age\":30}]";

Type listType = new TypeToken<List<Personne>>(){}.getType();
List<Personne> personnes = gson.fromJson(jsonArray, listType);

for (Personne p : personnes) {
    System.out.println(p.getNom() + " - " + p.getAge());
}

Configuration avancee de Gson

Gson gson = new GsonBuilder()
    .setPrettyPrinting()                    // Formatage lisible
    .serializeNulls()                       // Inclure les valeurs null
    .setDateFormat("yyyy-MM-dd HH:mm:ss")   // Format de date personnalise
    .excludeFieldsWithoutExposeAnnotation() // Utiliser @Expose
    .create();

Iteration sur les donnees JSON

Parcourir un JSONObject

Plusieurs methodes permettent d’iterer sur les proprietes d’un objet JSON :

JSONObject obj = new JSONObject()
    .put("nom", "Alice")
    .put("age", 25)
    .put("ville", "Paris");

// Methode 1 : Utiliser keys()
Iterator<String> cles = obj.keys();
while (cles.hasNext()) {
    String cle = cles.next();
    Object valeur = obj.get(cle);
    System.out.println(cle + " : " + valeur);
}

// Methode 2 : Utiliser keySet() (plus moderne)
for (String cle : obj.keySet()) {
    System.out.println(cle + " = " + obj.get(cle));
}

// Methode 3 : Convertir en Map
Map<String, Object> map = obj.toMap();
map.forEach((cle, valeur) -> System.out.println(cle + " -> " + valeur));

Parcourir un JSONArray

JSONArray arr = new JSONArray()
    .put("Java")
    .put("Python")
    .put("JavaScript")
    .put("Go");

// Methode 1 : Boucle classique avec index
for (int i = 0; i < arr.length(); i++) {
    System.out.println("Element " + i + ": " + arr.get(i));
}

// Methode 2 : Boucle for-each (Java 8+)
for (Object element : arr) {
    System.out.println(element);
}

// Methode 3 : Avec Stream API
arr.toList().stream()
    .filter(e -> e.toString().startsWith("J"))
    .forEach(System.out::println);

Parcourir des structures imbriquees

String jsonComplex = """
    {
        "utilisateur": {
            "nom": "Alice",
            "adresses": [
                {"ville": "Paris", "cp": "75001"},
                {"ville": "Lyon", "cp": "69001"}
            ]
        }
    }
    """;

JSONObject root = new JSONObject(jsonComplex);
JSONObject utilisateur = root.getJSONObject("utilisateur");
JSONArray adresses = utilisateur.getJSONArray("adresses");

for (int i = 0; i < adresses.length(); i++) {
    JSONObject adresse = adresses.getJSONObject(i);
    System.out.println(adresse.getString("ville") + " - " + adresse.getString("cp"));
}

Methodes optXXX vs getXXX

La difference entre ces deux familles de methodes est cruciale pour ecrire du code robuste :

Comportement des methodes getXXX

Les methodes getXXX() lancent une JSONException si la cle n’existe pas :

JSONObject obj = new JSONObject().put("foo", "bar");

System.out.println(obj.getString("foo"));   // "bar"
System.out.println(obj.getString("baz"));   // JSONException!

Comportement des methodes optXXX

Les methodes optXXX() retournent une valeur par defaut au lieu de lancer une exception :

JSONObject obj = new JSONObject().put("foo", "bar");

// Avec valeur par defaut implicite
System.out.println(obj.optString("foo"));        // "bar"
System.out.println(obj.optString("baz"));        // "" (chaine vide)
System.out.println(obj.optInt("count"));         // 0
System.out.println(obj.optBoolean("actif"));     // false

// Avec valeur par defaut explicite
System.out.println(obj.optString("baz", "N/A")); // "N/A"
System.out.println(obj.optInt("count", -1));     // -1

Quand utiliser quoi ?

SituationMethode recommandee
Propriete obligatoiregetXXX()
Propriete optionnelleoptXXX()
Validation stricte requisegetXXX() + try/catch
Code defensifoptXXX() avec valeur par defaut

Bonnes Pratiques

1. Toujours valider le JSON entrant

public JSONObject parseJsonSafely(String jsonString) {
    if (jsonString == null || jsonString.trim().isEmpty()) {
        return new JSONObject();
    }
    try {
        return new JSONObject(jsonString);
    } catch (JSONException e) {
        logger.error("JSON invalide: " + e.getMessage());
        return new JSONObject();
    }
}

2. Utiliser des classes DTO avec Gson

Plutot que de manipuler des JSONObject directement, definissez des classes :

public class ApiResponse {
    private boolean success;
    private String message;
    private List<Utilisateur> data;

    // Getters, setters...
}

// Utilisation
Gson gson = new Gson();
ApiResponse response = gson.fromJson(jsonString, ApiResponse.class);
if (response.isSuccess()) {
    response.getData().forEach(System.out::println);
}

3. Reutiliser les instances Gson

Creer une instance Gson est couteux. Reutilisez-la :

public class JsonUtils {
    private static final Gson GSON = new GsonBuilder()
        .setPrettyPrinting()
        .setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
        .create();

    public static String toJson(Object obj) {
        return GSON.toJson(obj);
    }

    public static <T> T fromJson(String json, Class<T> clazz) {
        return GSON.fromJson(json, clazz);
    }
}

4. Gerer les valeurs null explicitement

// Avec Gson - inclure les nulls si necessaire
Gson gson = new GsonBuilder().serializeNulls().create();

// Avec JSONObject - verifier avant utilisation
if (!obj.isNull("email")) {
    String email = obj.getString("email");
}

Pieges Courants

1. Confusion entre JSONObject et Map

// PIEGE : JSONObject n'est pas une Map standard
JSONObject obj = new JSONObject();
obj.put("cle", "valeur");

// Ceci ne fonctionne pas comme attendu
Map<String, Object> map = (Map<String, Object>) obj; // ClassCastException!

// Solution : utiliser toMap()
Map<String, Object> map = obj.toMap();

2. Probleme avec les nombres

JSONObject obj = new JSONObject("{\"id\": 123456789012345678}");

// PIEGE : perte de precision pour les grands nombres
long id = obj.getLong("id"); // Peut perdre de la precision

// Solution : utiliser getString pour les grands nombres
String idStr = obj.getString("id");
BigInteger id = new BigInteger(idStr);

3. Modification pendant l’iteration

// PIEGE : ConcurrentModificationException possible
for (String key : obj.keySet()) {
    if (key.startsWith("temp_")) {
        obj.remove(key); // Dangereux!
    }
}

// Solution : collecter d'abord, modifier ensuite
List<String> keysToRemove = new ArrayList<>();
for (String key : obj.keySet()) {
    if (key.startsWith("temp_")) {
        keysToRemove.add(key);
    }
}
keysToRemove.forEach(obj::remove);

4. Oublier le type erasure avec Gson

// PIEGE : ne fonctionne pas a cause du type erasure
List<Utilisateur> users = gson.fromJson(json, List.class);

// Solution : utiliser TypeToken
Type listType = new TypeToken<List<Utilisateur>>(){}.getType();
List<Utilisateur> users = gson.fromJson(json, listType);

5. Ne pas gerer les caracteres speciaux

// PIEGE : certains caracteres peuvent poser probleme
String texte = "Texte avec \"guillemets\" et \n retour ligne";

// JSONObject echappe automatiquement
JSONObject obj = new JSONObject().put("texte", texte);
System.out.println(obj.toString());
// {"texte":"Texte avec \"guillemets\" et \n retour ligne"}

Conclusion

La manipulation de JSON en Java offre plusieurs approches selon vos besoins :

org.json (JSONObject/JSONArray) est ideal pour :

  • La manipulation rapide et ad-hoc de donnees JSON
  • Les cas ou la structure JSON est dynamique ou inconnue
  • Les prototypes et scripts simples

Gson est preferable pour :

  • La serialisation/deserialisation vers des classes Java typees
  • Les projets avec des modeles de donnees bien definis
  • La configuration avancee (exclusions, formats personnalises)

En resume, voici les points cles a retenir :

  1. Choisissez la bonne bibliotheque selon votre cas d’usage
  2. Utilisez optXXX() pour un code plus robuste avec les proprietes optionnelles
  3. Definissez des classes DTO plutot que de manipuler des JSONObject bruts
  4. Reutilisez les instances Gson pour de meilleures performances
  5. Gerez toujours les exceptions lors du parsing JSON

La maitrise de ces outils vous permettra de travailler efficacement avec les APIs modernes et d’echanger des donnees de maniere fiable dans vos applications Java.

Ressources complementaires

Advertisement

In-Article Ad

Dev Mode

Share this article

Mahmoud DEVO

Mahmoud DEVO

Senior Full-Stack Developer

I'm a passionate full-stack developer with 10+ years of experience building scalable web applications. I write about Vue.js, Node.js, PostgreSQL, and modern DevOps practices.

Enjoyed this article?

Subscribe to get more tech content delivered to your inbox.

Related Articles