Aller au contenu principal

Convertir JSON en Java

JSON vers classes Java génère des records ou des POJOs à partir d’un document d’exemple, dans votre navigateur. Les champs numériques optionnels sont encapsulés — Integer plutôt que int — car un primitif ne peut pas contenir null, donc une clé manquante se désérialise en 0 et devient indiscernable d’un vrai zéro.

100 % local
Structure
Exemple de JSON
0 B1 ligneLig. 1, Col. 1
Erreur de syntaxe · Erreur à la ligne 1, colonne 1

Le document s’arrête trop tôt — il semble tronqué.


^
Code générélecture seule
0 B1 ligne
Si vous en avez, collez plusieurs enregistrements. Cela permet de repérer les champs facultatifs absents de certaines lignes.

Comment fonctionne Convertir JSON en Java ?

Les types primitifs de Java rendent la question des champs optionnels concrète plutôt que stylistique, et se tromper produit un bug réellement difficile à trouver.

Un primitif ne peut pas être absent

int count désérialise une clé count manquante en 0. Aucune exception, aucun avertissement — et en aval, impossible de distinguer un enregistrement où le count n’a jamais été envoyé d’un enregistrement où le count valait vraiment zéro. Même chose pour boolean, qui devient false, et pour double, qui devient 0.0. Les champs optionnels et nullables sont donc encapsulés : Integer, Long, Double, Boolean, qui peuvent tous contenir null et vous permettent de poser la question.

Les génériques ne peuvent contenir aucun primitif

List<int> ne compile pas. Chaque élément de liste est encapsulé, optionnel ou non, c’est pourquoi un tableau d’entiers devient List<Integer>.

record ou POJO

Un record est le meilleur choix par défaut sur Java 17 et au-delà : immuable, pas de boilerplate, equals, hashCode et toString gratuits, et Jackson les prend en charge depuis la 2.12. Un POJO avec champs privés, getters et setters est ce que voudra une base de code en Java 8 ou un framework qui exige un constructeur sans argument, donc les deux sont disponibles.

Les annotations Jackson portent la clé d’origine

La convention Java est le camelCase ; les clés JSON ne le sont souvent pas. Plutôt que de dépendre d’une PropertyNamingStrategy configurée ailleurs, chaque composant reçoit un @JsonProperty explicite avec la clé exacte du document. La classe se lie alors correctement, quelle que soit la configuration de l'ObjectMapper.

Un type public par fichier

Java n’autorise qu’exactement un type public de premier niveau par fichier source, donc un document qui produit plusieurs types ne compile pas collé en un seul bloc. La sortie le signale dans un commentaire d’en-tête : enregistrez chaque type sous <TypeName>.java, ou imbriquez-les dans une classe externe. Émettre un fichier que javac rejette sans le mentionner est le genre de petite malhonnêteté qui fait perdre dix minutes.

Exemple

[
  { "user_id": 1, "retries": 0, "tags": ["a"] },
  { "user_id": 2, "tags": [] }
]

Généré

public record User(
    @JsonProperty("user_id") int userId,
    @JsonProperty("retries") Integer retries,
    @JsonProperty("tags") List<String> tags
) {}

Quelles options et quels cas limites Convertir JSON en Java prend en charge ?

Référence technique et options
ParamètreTypeValeur par défautComportement et cas limites
Formerecord / POJOrecordrecord sur Java 17+ pour un DTO immuable sans code passe-partout. POJO pour Java 8, ou pour tout ce qui a besoin d’un constructeur sans argument et des setters.
Paquetidentifiant(aucun)Ajoute une déclaration de package. Laissez-le vide pour un fichier de test ; définissez-le pour qu’il corresponde au répertoire où le fichier sera placé.
JacksonbooléenonÉmet @JsonProperty avec la clé JSON exacte, ainsi le binding ne dépend pas d’une stratégie de nommage ObjectMapper configurée ailleurs.
Encapsuler les optionnelsbooléenonUn int optionnel devient Integer. Le désactiver fait qu’une clé manquante se désérialise en 0, ce qui est indiscernable d’un zéro réel.
stringtype JavaStringLes formats détectés ne sont pas mappés sur Instant, LocalDate ou UUID. Jackson a besoin que JavaTimeModule soit enregistré pour les deux premiers, et il lève une exception sur tout record dont le format diffère.
Entiertype Javaint / longlong quand n’importe quel exemple dépasse 2,147,483,647. Un nombre JSON ne déclare pas de largeur, donc la largeur est lue à partir des valeurs.
Tableautype JavaList<T>Les éléments sont toujours boxed, car les génériques ne peuvent pas contenir de types primitifs. Un tableau mixte devient List<Object>.
Objet imbriquétypetype proprePromu à son propre record ou classe, déclaré avant le type qui l’utilise. Les formes identiques partagent un seul type plutôt que de générer des doublons numérotés.

Questions fréquentes

Pourquoi un champ est-il int et un autre Integer ?

Le Integer apparaissait dans certains enregistrements et pas dans d’autres. Un int primitif ne peut pas contenir null, donc Jackson désérialise une clé manquante en 0 — et rien en aval ne permet de le distinguer d’un enregistrement qui a vraiment envoyé zéro. Integer peut être null, ce qui rend l’absence visible. Les champs présents dans tous les enregistrements restent primitifs, ce qui est moins coûteux et plus simple.

Puis-je coller toute la sortie dans un seul fichier ?

Pas si elle a généré plus d’un type. Java n’autorise qu’un seul type public de premier niveau par fichier source, donc javac le rejettera. Enregistrez chaque type sous <TypeName>.java, ou transformez les types imbriqués en classes imbriquées statiques à l’intérieur d’une classe externe. La sortie indique en tête dans quel cas vous êtes.

record ou POJO ?

record si vous êtes sur Java 17 ou plus récent et que l’objet est une donnée arrivée de l’extérieur : il est immuable, il vous donne equals, hashCode et toString correctement, et Jackson prend en charge les records depuis la 2.12. POJO si vous êtes sur Java 8, si un framework exige un constructeur sans argument et des setters (JPA ancien, certaines configurations Spring), ou si l’objet a réellement besoin d’être modifié après construction.

Pourquoi mon horodatage est-il un String plutôt qu’un Instant ?

Parce que Jackson ne peut pas le parser en Instant sans JavaTimeModule enregistré, et parce qu’il lève une exception sur le premier enregistrement dont le format diffère de celui attendu. Les vraies API envoient des secondes Unix, des millisecondes Unix, de l’ISO 8601 avec ou sans décalage, et parfois quelque chose de régional. Le format détecté est signalé dans la référence ci-dessus, pour que vous puissiez changer le type en connaissance de cause et ajouter un convertisseur si le format en exige un.

Ai-je besoin de Lombok ?

Non, et le générateur n’émet délibérément pas de @Data ni de @Builder. Sur Java 17+, un record couvre ce à quoi servait le @Value de Lombok, sans processeur d’annotations dans votre build. La sortie POJO est du Java simple avec de vrais getters et setters, qui compile partout. Si votre projet utilise déjà Lombok, vous pouvez remplacer les accesseurs vous-même, mais rien ici ne l’exige.

Mon JSON est-il envoyé ?

Non. Parsing, inférence de types et rendu s’exécutent tous dans votre navigateur — ouvrez le panneau Réseau pendant que vous collez et vous ne verrez rien partir. Les échantillons que les gens collent dans un générateur de classes sont généralement de vraies réponses d’un système auquel ils s’intègrent, précisément ce qui ne devrait pas passer par un serveur inconnu.