Table of Contents
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
JSONObjectetJSONArray - 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 ?
| Situation | Methode recommandee |
|---|---|
| Propriete obligatoire | getXXX() |
| Propriete optionnelle | optXXX() |
| Validation stricte requise | getXXX() + try/catch |
| Code defensif | optXXX() 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 :
- Choisissez la bonne bibliotheque selon votre cas d’usage
- Utilisez optXXX() pour un code plus robuste avec les proprietes optionnelles
- Definissez des classes DTO plutot que de manipuler des JSONObject bruts
- Reutilisez les instances Gson pour de meilleures performances
- 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
In-Article Ad
Dev Mode
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
Convertissez un JSON en Java : Parsing et conversion de donn
Voici une proposition de meta description pour votre article : "Apprenez à extraire des données JSON avec Java et Gson ! Découvrez comment convertir un objet J
Manipuler les classes Java avec ASM et Javassist : bytecode, instrumentation et fichiers JAR
Apprenez a manipuler les classes Java avec ASM et Javassist : chargement, modification du bytecode, instrumentation et creation de fichiers JAR.
Synchronisation Java avec AtomicInteger : eviter la contention et optimiser les performances
Decouvrez comment utiliser les types atomiques Java (AtomicInteger, AtomicLong, AtomicReference, AtomicBoolean) pour reduire la contention, eviter les blocages et ameliorer les performances.