JSON vers Java
Générer des classes Java POJO depuis du JSON
Entrée JSON
Sortie Java
Qu'est-ce que la conversion JSON vers classe Java ?
La conversion JSON vers classe Java prend un objet JSON brut et produit des définitions de Plain Old Java Object (POJO) avec des champs privés, des getters et des setters. Java ne possède pas de système de types JSON natif : toute réponse d'API JSON, tout fichier de configuration ou payload de message nécessite une classe correspondante avant de pouvoir être manipulé de façon typée. Des bibliothèques comme Jackson et Gson font correspondre les clés JSON aux champs Java par réflexion, mais elles requièrent que les définitions de classes existent au préalable.
Un POJO Java standard pour la désérialisation JSON déclare un champ privé pour chaque clé JSON, un constructeur sans argument, et une paire getter/setter par champ. Les objets JSON imbriqués deviennent des classes séparées. Les tableaux deviennent des champs List<T> avec un import java.util.List. Les types JSON primitifs correspondent aux primitives Java (int, double, boolean) ou à leurs types enveloppants (Integer, Double, Boolean) lorsqu'ils sont utilisés dans des génériques. Les valeurs nulles correspondent généralement à Object ou à un type référence nullable.
Écrire ces définitions de classes à la main est répétitif. Vous lisez chaque clé JSON, déduisez le type Java depuis la valeur, convertissez les conventions de nommage du camelCase JSON vers les champs Java camelCase, créez des noms de classes PascalCase pour les objets imbriqués, et ajoutez le code répétitif des getters et setters. Pour un objet JSON avec 15 champs et 3 objets imbriqués, cela représente 4 classes, plus de 30 méthodes, et tout doit rester cohérent. Un convertisseur accomplit cela en quelques millisecondes.
Pourquoi utiliser un convertisseur JSON vers Java ?
Créer des POJOs Java manuellement depuis du JSON implique d'inspecter chaque champ, de déduire les types depuis des valeurs d'exemple, d'écrire les paires getter/setter, et de répéter le processus pour chaque objet imbriqué. Quand le contrat d'API change, tout est à mettre à jour à la main. Un convertisseur supprime ce travail mécanique.
Cas d'usage du JSON vers Java
Correspondance des types JSON vers Java
Chaque valeur JSON correspond à un type Java spécifique. Le tableau ci-dessous montre comment le convertisseur traduit chaque type JSON en son équivalent Java. La colonne Alternative présente les types enveloppants utilisés dans les contextes génériques comme List<T>, ou les fonctionnalités Java plus récentes comme les Records.
| Type JSON | Exemple | Type Java | Alternative |
|---|---|---|---|
| string | "hello" | String | String |
| number (integer) | 42 | int | int / Integer |
| number (float) | 3.14 | double | double / Double |
| boolean | true | boolean | boolean / Boolean |
| null | null | Object | Object (or @Nullable String) |
| object | {"k": "v"} | NestedClass | Record (Java 16+) |
| array of strings | ["a", "b"] | List<String> | List<String> |
| array of objects | [{"id": 1}] | List<Item> | List<Item> |
| mixed array | [1, "a"] | List<Object> | List<Object> |
Référence des annotations JSON Java
Lors de la désérialisation JSON avec Jackson ou Gson, les annotations contrôlent comment les clés JSON correspondent aux champs Java, comment les champs inconnus sont gérés, et comment les valeurs nulles sont traitées. Cette référence couvre les annotations les plus fréquentes lorsqu'on travaille avec des POJOs générés.
| Annotation | Rôle | Bibliothèque |
|---|---|---|
| @JsonProperty("name") | Maps a JSON key to a Java field with a different name | Jackson |
| @SerializedName("name") | Same as @JsonProperty, but for the Gson library | Gson |
| @JsonIgnoreProperties | Ignores unknown JSON keys during deserialization instead of failing | Jackson |
| @Nullable | Marks a field as accepting null values from JSON input | JSR 305 / JetBrains |
| @NotNull | Enforces that a field must not be null, throws on violation | Bean Validation |
| @JsonFormat(pattern=...) | Defines a date/time format for serialization and deserialization | Jackson |
POJO vs Record vs Lombok
Java propose trois approches courantes pour définir des structures typées afin de contenir des données JSON. Chacune convient à un style de projet et à une version Java différents. Les POJOs sont le pattern traditionnel avec la plus large compatibilité. Les Records réduisent le code répétitif pour les données immuables. Lombok génère les getters, setters et constructeurs à la compilation via des annotations.
Exemples de code
Ces exemples montrent comment utiliser des POJOs Java générés avec Jackson pour la désérialisation, comment produire des classes Java programmatiquement depuis JavaScript et Python, et comment utiliser l'outil CLI jsonschema2pojo pour la génération en lot.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private int id;
private String name;
private String email;
private boolean active;
private double score;
private Address address;
private List<String> tags;
// getters and setters omitted for brevity
public static void main(String[] args) throws Exception {
String json = "{\"id\":1,\"name\":\"Alice\",\"email\":\"alice@example.com\",\"active\":true,\"score\":98.5,\"address\":{\"street\":\"123 Main St\",\"city\":\"Springfield\",\"zip\":\"12345\"},\"tags\":[\"admin\",\"user\"]}";
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
System.out.println(user.getName()); // -> Alice
}
}
class Address {
private String street;
private String city;
private String zip;
// getters and setters
}// Minimal JSON-to-Java-POJO generator in JS
function jsonToJava(obj, name = "Root") {
const classes = [];
function infer(val, fieldName) {
if (val === null) return "Object";
if (typeof val === "string") return "String";
if (typeof val === "number") return Number.isInteger(val) ? "int" : "double";
if (typeof val === "boolean") return "boolean";
if (Array.isArray(val)) {
const first = val.find(v => v !== null);
if (!first) return "List<Object>";
const elem = infer(first, fieldName);
const boxed = elem === "int" ? "Integer" : elem === "double" ? "Double" : elem === "boolean" ? "Boolean" : elem;
return `List<${boxed}>`;
}
if (typeof val === "object") {
const cls = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
build(val, cls);
return cls;
}
return "Object";
}
function build(obj, cls) {
const fields = Object.entries(obj).map(([k, v]) => {
const type = infer(v, k);
return ` private ${type} ${k};`;
});
classes.push(`public class ${cls} {\n${fields.join("\n")}\n}`);
}
build(obj, name);
return classes.join("\n\n");
}
console.log(jsonToJava({ id: 1, name: "Alice", scores: [98, 85] }, "User"));
// public class User {
// private int id;
// private String name;
// private List<Integer> scores;
// }import json
def json_to_java(obj: dict, class_name: str = "Root") -> str:
classes = []
def infer(val, name):
if val is None:
return "Object"
if isinstance(val, bool):
return "boolean"
if isinstance(val, int):
return "int"
if isinstance(val, float):
return "double"
if isinstance(val, str):
return "String"
if isinstance(val, list):
if not val:
return "List<Object>"
elem = infer(val[0], name)
boxed = {"int": "Integer", "double": "Double", "boolean": "Boolean"}.get(elem, elem)
return f"List<{boxed}>"
if isinstance(val, dict):
cls = name[0].upper() + name[1:]
build(val, cls)
return cls
return "Object"
def build(obj, cls):
fields = [f" private {infer(v, k)} {k};" for k, v in obj.items()]
classes.append(f"public class {cls} {{\n" + "\n".join(fields) + "\n}")
build(obj, class_name)
return "\n\n".join(classes)
data = json.loads('{"id": 1, "name": "Alice", "tags": ["admin"]}')
print(json_to_java(data, "User"))
# public class User {
# private int id;
# private String name;
# private List<String> tags;
# }# Install jsonschema2pojo (requires Java 8+)
# Download from https://github.com/joelittlejohn/jsonschema2pojo
# Generate POJOs from a JSON file
jsonschema2pojo --source user.json --target src/main/java \
--source-type json --annotation-style jackson2
# Generate with Gson annotations instead
jsonschema2pojo --source user.json --target src/main/java \
--source-type json --annotation-style gson
# From a JSON string via stdin
echo '{"id": 1, "name": "Alice", "tags": ["admin"]}' | \
jsonschema2pojo --source-type json --annotation-style jackson2 \
--target src/main/java --target-package com.example.model