IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

 

Développons en Java   2.30  
Copyright (C) 1999-2022 Jean-Michel DOUDOUX    (date de publication : 15/06/2022)

[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

 

56. JSON-P (Java API for JSON Processing)

 

chapitre    5 6

 

Niveau : niveau 3 Intermédiaire 

 

La JSR 353 définit une API standardisée qui permet de parser et générer un document JSON : JSON-P 1.0. Elle ne propose rien concernant le binding entre un document JSON et un objet Java.

Deux API sont proposées :

  • Streaming API : API de bas niveau qui permet la consommation et la production d'un document JSON en utilisant un flux d'événements, de manière similaire à l'API StAX
  • Object Model API : API de plus haut niveau qui utilise des objets, de manière similaire à DOM. Cette API utilise l'API Streaming.

Les classes et interfaces de l'API JSON-P sont contenues dans deux packages :

  • javax.json : contient les classes et interfaces de l'Object Model API
  • javax.json.stream : contient les classes et interfaces de la Streaming API

Les principales classes et interfaces du package javax.json sont :

Classe ou interface

Description

Json

Fabrique qui permet de créer des instances de certains types ou fabriques de l'API (Parser, Builder, Generator, Writer, Reader)

JsonReader

Créer un modèle objets à partir d'une représentation Json des données

JsonObjectBuilder
JsonArrayBuilder

Créer un modèle objets ou un tableau en lui ajoutant des éléments

JsonWriter

Envoyer dans un flux une représentation Json d'un modèle objet

JsonValue
JsonStructure
JsonObject
JsonArray
JsonString
JsonNumber

Encapsule les types de données d'un élément JSON

JsonStructure, JsonObject, JsonArray, JsonString et JsonNumber sont des sous-types de JsonValue

JsonObject et JsonArray sont des sous-types de JsonStructure

JsonException

Exception pouvant être levée lors du traitement de la représentation JSON


Les principales classes et interfaces du package javax.json.stream sont :

Classe ou interface

Rôle

JsonParser

Parser un document JSON en émettant des événements

JsonGenerator

Ecrire un document JSON : chaque élément est écrit un par un


Ce chapitre contient plusieurs sections :

 

56.1. La classe Json

La classe Json est une fabrique qui permet de créer des instances des différents types d'objets à utiliser pour mettre en oeuvre l'API.

Méthode 

Rôle

static JsonArrayBuilder createArrayBuilder()

Créer une instance de type JsonArrayBuilder

static JsonBuilderFactory createBuilderFactory(Map<String,?> config)

Créer une instance de type JsonBuilderFactory

static JsonGenerator createGenerator(OutputStream out)

Créer une instance de type JSonGenerator pour écrire le document JSON dans un flux d'octets

static JsonGenerator createGenerator(Writer writer)

Créer une instance de type JSonGenerator pour écrire le document JSON dans un flux de caractères

static JsonGeneratorFactory createGeneratorFactory(Map<String,?> config)

Créer une instance de type JsonGeneratorFactory

static JsonObjectBuilder createObjectBuilder()

Créer une instance de type JsonObjectBuilder

static JsonParser createParser(InputStream in)

Créer une instance de type JsonParser pour parser un document JSON à partir d'un flux d'octets

static JsonParser createParser(Reader reader)

Créer une instance de type JsonParser pour parser un document JSON à partir d'un flux de caractères

static JsonParserFactory createParserFactory(Map<String,?> config)

Créer une instance de type JsonParserFactory

static JsonReader createReader(InputStream in)

Créer une instance de type JsonReader pour lire un document JSON à partir d'un flux d'octets

static JsonReader createReader(Reader reader)

Créer une instance de type JsonReader pour lire un document JSON à partir d'un flux de caractères

static JsonReaderFactory createReaderFactory(Map<String,?> config)

Créer une instance de type JsonReaderFactory

static JsonWriter createWriter(OutputStream out)

Créer une instance de type JsonWriter pour écrire un document JSON dans d'un flux d'octets

static JsonWriter createWriter(Writer writer)

Créer une instance de type JsonWriter pour écrire un document JSON dans d'un flux de caractères

static JsonWriterFactory createWriterFactory(Map<String,?> config)

Créer une instance de type JsonWriterFactory

 

56.2. L'API Streaming

L'API Streaming permet de parcourir et de générer un document JSON sous la forme d'un flux.

Elle définit plusieurs interfaces :

  • JsonParser : parser un document JSON selon des événements
  • JsonParserFactory : fabrique d'instances de type JsonParser configurable
  • JsonGenerator : écrire chacun des éléments d'un document JSON
  • JsonGeneratorFactory : fabrique d'instances de type JsonGenerator configurable

 

56.2.1. L'interface JsonParser

L'interface javax.json.stream.JsonParser définit des méthodes pour parser un document JSON et émettre des événements durant le parcours d'une manière similaire à un XMLStreamReader de l'API StaX.

Les différents événements sont définis dans l'énumération JsonParser.Event

Constante

Rôle

END_ARRAY

Fin d'un tableau JSON

END_OBJECT

Fin d'un objet JSON

KEY_NAME

Nom d'une clé dans une paire nom/valeur d'un objet JSON

START_ARRAY

Début d'un tableau JSON

START_OBJECT

Début d'un objet JSON

VALUE_FALSE

La valeur false (dans un objet ou un tableau JSON)

VALUE_NULL

La valeur null (dans un objet ou un tableau JSON)

VALUE_NUMBER

Une valeur numérique (dans un objet ou un tableau JSON)

VALUE_STRING

La valeur alphanumérique (dans un objet ou un tableau JSON)

VALUE_TRUE

La valeur true (dans un objet ou un tableau JSON)


L'interface JsonParser définit plusieurs méthodes :

Méthode 

Rôle

void close()

Fermer le parser et libérer les éventuelles ressources associées

BigDecimal getBigDecimal()

Renvoyer la valeur numérique courante sous la forme d'un BigDecimal

int getInt()

Renvoyer la valeur numérique courante sous la forme d'un entier

JsonLocation getLocation()

Renvoyer un objet qui encapsule la localisation courante du parser dans le document

long getLong()

Renvoyer la valeur numérique de la valeur courante

String getString()

Renvoyer sous forme d'une chaîne de caractères la valeur courante

boolean hasNext()

Renvoyer un booléen qui précise si le parcours n'est pas encore terminé en renvoyant true sinon renvoie false

boolean isIntegralNumber()

Renvoyer un booléen qui précise si la valeur numérique courante est un entier

JsonParser.Event next()

Renvoyer l'événement suivant


L'utilisation de l'API Streaming se fait en plusieurs étapes :

  • obtenir une instance de la classe JsonParser
  • itérer sur chaque événement en utilisant les méthodes hasNext() et next()
  • traiter chaque événement au besoin selon son type en utilisant les méthodes de l'instance du parser pour obtenir les informations utiles
  • invoquer explicitement la méthode close() ou implicitement en utilisant une instruction try avec ressources à partir de Java 7

Pour obtenir une instance de type JsonParser, il y a deux solutions :

  • invoquer une des surcharges de la méthode createParser() de la classe Json qui attend en paramètre un objet de type InputStream ou Reader
  • obtenir une instance de type JsonParserFactory en invoquant la méthode Json.createParserFactory() et invoquer la méthode createParser() sur cette instance. Cette façon de faire permet de configurer l'instance

Différentes informations peuvent être obtenues lors du parcours en utilisant des méthodes d'une instance de type JsonParser selon le type d'événement en cours de traitement :

  • la valeur de l'élément courant en invoquant la méthode getString() pour les événements KEY_NAME, VALUE_STRING et VALUE_NUMBER
  • la valeur de l'élément courant en invoquant les méthodes getNumberType(), getIntValue(), getLongValue(), getBigDecimalValue() et isIntegralNumber() pour l'événement VALUE_NUMBER
Exemple ( code Java 7 ) :
      String document = "[{\n" + "\"nom\":\"nom1\", \"prenom\": \"prenom1\", \"taille\": 175\n"
              + "},\n"
              + "{\n"
              + "\"nom\": \"nom2\", \"prenom\": \"prenom2\",\"taille\": 183\n" + "}\n"
              + "]";
      try (JsonParser parser = Json.createParser(new StringReader(document))) {
        Event event = null;
        while (parser.hasNext()) {
          event = parser.next();
          System.out.print("event=" + event);
          switch (event) {
            case KEY_NAME:
              System.out.print(" cle=" + parser.getString());
              break;
            case VALUE_STRING:
              System.out.print(" valeur=" + parser.getString());
              break;
            case VALUE_NUMBER:
              if (parser.isIntegralNumber()) {
                System.out.println(" valeur=" + parser.getInt());
              } else {
                System.out.println(" valeur=" + parser.getBigDecimal());
              }
              break;
            case VALUE_NULL:
              System.out.print(" valeur=null");
              break;
          }
          System.out.println("");
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
Résultat :
event=START_ARRAY
event=START_OBJECT
event=KEY_NAME
cle=nom
event=VALUE_STRING
valeur=nom1
event=KEY_NAME
cle=prenom
event=VALUE_STRING
valeur=prenom1
event=KEY_NAME
cle=taille
event=VALUE_NUMBER
valeur=175
event=END_OBJECT
event=START_OBJECT
event=KEY_NAME
cle=nom
event=VALUE_STRING
valeur=nom2
event=KEY_NAME
cle=prenom
event=VALUE_STRING
valeur=prenom2
event=KEY_NAME
cle=taille
event=VALUE_NUMBER
valeur=183
event=END_OBJECT
event=END_ARRAY

L'utilisation de la Streaming API est très efficace pour parser un document JSON par contre elle implique un surplus de code car il faut gérer chacun des événements.

 

56.2.2. L'interface JsonGenerator

L'interface javax.json.stream.JsonGenerator définit des méthodes pour faciliter l'ajout d'éléments JSON dans un flux d'octets ou de caractères.

Méthode

Rôle

void close()

Libérer les ressources associées au générateur

void flush()

Flush les données dans le flux associé

JsonGenerator write(BigDecimal value)

Ecrire la valeur numérique dans le tableau

JsonGenerator write(BigInteger value)

Ecrire la valeur numérique dans le tableau

JsonGenerator write(boolean value)

Ecrire la valeur booléenne dans le tableau

JsonGenerator write(double value)

Ecrire la valeur numérique dans le tableau

JsonGenerator write(int value)

Ecrire la valeur numérique dans le tableau

JsonGenerator write(JsonValue value)

Ecrire la valeur dans le tableau

JsonGenerator write(long value)

Ecrire la valeur numérique dans le tableau

JsonGenerator write(String value)

Ecrire la chaîne de caractères dans le tableau

JsonGenerator write(String name, BigDecimal value)

Ecrire la valeur numérique associée au nom fourni en paramètres

JsonGenerator write(String name, BigInteger value)

Ecrire la valeur numérique associée au nom fourni en paramètres

JsonGenerator write(String name, boolean value)

Ecrire la valeur booléenne associée au nom fourni en paramètres

JsonGenerator write(String name, double value)

Ecrire la valeur numérique associée au nom fourni en paramètres

JsonGenerator write(String name, int value)

Ecrire la valeur numérique associée au nom fourni en paramètres

JsonGenerator write(String name, JsonValue value)

Ecrire la valeur associée au nom fourni en paramètres

JsonGenerator write(String name, long value)

Ecrire la valeur numérique associée au nom fourni en paramètres

JsonGenerator write(String name, String value)

Ecrire la chaîne de caractères associée au nom fourni en paramètres

JsonGenerator writeEnd()

Ecrire un marqueur de fin pour l'élément courant

JsonGenerator writeNull()

Ecrire la valeur JSON null dans le tableau

JsonGenerator writeNull(String name)

Ecrire la valeur JSON null associée au nom fourni en paramètres

JsonGenerator writeStartArray()

Ecrire un marqueur de début de tableau

JsonGenerator writeStartArray(String name)

Ecrire un marqueur de début de tableau associé au nom fourni en paramètres

JsonGenerator writeStartObject()

Ecrire un marqueur de début d'objet dans le tableau

JsonGenerator writeStartObject(String name)

Ecrire un marqueur de début d'objet associé au nom fourni en paramètres


Pour obtenir une instance de type JsonGenerator, il y a deux solutions :

  • Invoquer une des surcharges de la méthode createGenerator() de la classe Json qui attend en paramètre un objet de type InputStream ou Reader
  • Obtenir une instance de type JsonParserFactory en invoquant la méthode Json.createGeneratorFactory() et invoquer la méthode createGenerator() sur cette instance. Cette façon de faire permet de configurer l'instance

Les méthodes write() mettent en oeuvre le principe de fluent API ce qui permet de chaîner leurs invocations.

Exemple :
    StringWriter sw = new StringWriter();
    JsonGenerator jsonGen = Json.createGenerator(sw);
    jsonGen.writeStartArray()
           .writeStartObject()
           .write("nom", "nom1")
           .write("prenom", "prenom1")
           .write("taille", "175")
           .writeEnd()
           .writeStartObject()
           .write("nom", "nom2")
           .write("prenom", "prenom2")
           .write("taille", "183")
           .writeEnd()
           .writeEnd()
           .close();
    String doc = sw.toString();
    System.out.println(doc);
Résultat :
[{"nom":"nom1","prenom":"prenom1","taille":"175"},
{"nom":"nom2","prenom":"prenom2","taille":"183"}]

L'utilisation de cette interface est similaire à celle de l'interface XMLStreamWriter de l'API Stax.

Il est important d'invoquer explicitement la méthode close() ou implicitement en utilisant une instruction try with resources à partir de Java 7.

 

56.3. L'API Object Model

L'API Object Model est de plus haut niveau, en permettant notamment :

  • de créer un objet ou un graphe d'objets à partir de leur représentation JSON
  • de naviguer dans le graphe d'objets et de le modifier
  • de sérialiser les objets du graphe dans leur représentation JSON

Plusieurs classes permettent de faciliter la manipulation de ces objets :

  • JsonObjectBuilder : permet de créer des instances de type JsonObject et JsonArray
  • JsonReader : permet de lire un document JSON
  • JsonWriter : permet d'écrire un document JSON

 

56.3.1. Les classes qui encapsulent un élément d'un document Json

L'API Object Model propose plusieurs interfaces qui définissent les différentes fonctionnalités des éléments d'un document JSON :

  • JsonObject : un objet JSON
  • JsonArray : un tableau JSON
  • JsonString : une valeur de type chaîne de caractères
  • JsonNumber : une valeur de type numérique

 

56.3.1.1. L'interface JsonValue

L'interface JsonValue définit les fonctionnalités d'une classe qui encapsule de manière immuable une valeur d'un document JSON.

Elle possède plusieurs interfaces filles : JsonStructure, JsonArray, JsonObject, JsonString et JsonNumber.

Elle définit trois valeurs particulières :

  • JsonValue.TRUE
  • JsonValue.FALSE
  • JsonValue.NULL

Elle possède la classe interne JsonValue.ValueType qui est une énumération des différents types de valeur :

Enumération 

Rôle

ARRAY 

la valeur est un tableau

FALSE 

la valeur false

NULL 

la valeur null

NUMBER 

la valeur est un numérique

OBJECT 

la valeur est un objet

STRING 

la valeur est une chaîne de caractères

TRUE 

la valeur true


Elle définit plusieurs méthodes :

Méthode

Rôle

JsonValue.ValueType getValueType()

Renvoyer le type de la valeur

String toString()

Renvoyer une représentation sous forme d'une chaîne de caractères de la valeur

 

56.3.1.2. L'interface JsonNumber

L'interface JsonNumber définit les méthodes pour une classe qui encapsule de manière immuable une valeur numérique d'un document JSON.

Méthode

Rôle

BigDecimal bigDecimalValue()

Renvoyer la valeur sous la forme d'un BigDecimal

BigInteger bigIntegerValue()

Renvoyer la valeur sous la forme d'un BigInteger

BigInteger bigIntegerValueExact()

Renvoyer la valeur sous la forme d'un BigInteger

double doubleValue()

Renvoyer la valeur sous la forme d'un double

boolean equals(Object obj)

Comparer l'égalité entre l'instance courante et celle fournie en paramètre

int intValue()

Renvoyer la valeur sous la forme d'un entier de type double

int intValueExact()

Renvoyer la valeur sous la forme d'un entier de type double

boolean isIntegral()

Renvoyer un boolean qui précise si la valeur est entière

long longValue()

Renvoyer la valeur sous la forme d'un entier de type long

long longValueExact()

Renvoyer la valeur sous la forme d'un entier de type long

String toString()

Renvoyer une représentation sous forme d'une chaîne de caractères de la valeur

 

56.3.1.3. L'interface JsonString

L'interface JsonString définit les méthodes pour une classe qui encapsule de manière immuable une valeur d'un document JSON qui est une chaîne de caractères.

Méthode

Rôle

boolean equals(Object obj)

Comparer l'égalité entre l'instance courante et celle fournie en paramètre

CharSequence getChars()

Renvoyer une séquence de caractères de la valeur

String getString()

Renvoyer la valeur

 

56.3.1.4. L'interface JsonStructure

L'interface JsonStructure est l'interface mère des interfaces JsonObject et JsonArray. Elle hérite de l'interface JsonValue.

 

56.3.1.5. L'interface JsonObject

L'interface javax.json.JsonObjet définit les méthodes d'une classe qui encapsule un objet JSON immuable. Un objet JSON est composé de paires clé/valeur.

Les valeurs encapsulées dans un JsonObject peuvent être :

  • une instance de type JsonString, JsonNumber, JsonObjet, JsonArray
  • une des constantes : JsonValue.TRUE, JsonValue.FALSE, JsonValue.NULL

Elle hérite des interfaces JsonStructure et Map<String, JsonValue>.

Pour obtenir une instance de type JsonReader, il faut soit :

  • invoquer la méthode readObject() d'une instance de type JsonReader
  • invoquer la méthode build() d'une instance de type JsonObjectBuilder

L'interface propose plusieurs méthodes pour obtenir les différentes valeurs encapsulées dans l'instance :

Méthode 

Rôle

boolean getBoolean(String name)

Renvoyer la valeur booléenne associée à la clé

boolean getBoolean(String name, boolean defaultValue)

Renvoyer la valeur booléenne associée à la clé avec une valeur par défaut si la clé n'est pas trouvée

int getInt(String name)

Renvoyer la valeur entière associée à la clé : elle invoque la méthode getJsonNumber(name).intValue()

int getInt(String name, int defaultValue)

Renvoyer la valeur entière associée à la clé avec une valeur par défaut si la clé n'est pas trouvée

JsonArray getJsonArray(String name)

Renvoyer l'instance de type JsonArray encapsulant les données du tableau associées à la clé

JsonNumber getJsonNumber(String name)

Renvoyer l'instance de type JsonNumber encapsulant la valeur numérique associée à la clé

JsonObject getJsonObject(String name)

Renvoyer l'instance de type JsonObject encapsulant les données de l'objet associées à la clé

JsonString getJsonString(String name)

Renvoyer la chaîne de caractères associée à la clé

String getString(String name)

Renvoyer la chaîne de caractères associée à la clé : elle invoque la méthode getJsonString(name).getString()

String getString(String name, String defaultValue)

Renvoyer la chaîne de caractères associée à la clé avec la valeur par défaut si la clé n'est pas trouvée

boolean isNull(String name)

Renvoyer un booléen qui précise si la valeur associée à la clé est JsonValue.NULL


L'interface JsonObject hérite de l'interface Map mais les données qu'elle encapsule sont immuables : toute tentative de modification de la collection lèvera une exception de type UnsupportedException.

L'itération sur les éléments contenus dans le JsonObjet se fait dans l'ordre dans lequel les éléments ont été ajoutés.

 

56.3.1.6. L'interface JsonArray

L'interface javax.json.JsonArray définit les méthodes pour une classe qui encapsule un tableau immuable de valeurs JSON. Elle hérite des interfaces JsonStructure et List<JsonValue>.

Pour obtenir une instance de type JsonReader, il faut soit :

  • invoquer la méthode readArray() d'une instance de type JsonReader
  • invoquer la méthode build() d'une instance de type JsonArrayBuilder

Les valeurs encapsulées dans un JsonObject peuvent être :

  • une instance de type JsonString, JsonNumber, JsonObjet, JsonArray
  • une des constantes : JsonValue.TRUE, JsonValue.FALSE, JsonValue.NULL

L'interface JsonArray hérite de l'interface List mais les données qu'elle encapsule sont immuables : oute tentative de modification de la collection lèvera une exception de type UnsupportedException.

L'interface propose plusieurs méthodes pour obtenir les différentes valeurs encapsulées dans l'instance :

Méthode

Rôle

boolean getBoolean(int index)

Renvoyer la valeur booléenne de l'index fourni

boolean getBoolean(int index, boolean defaultValue)

Renvoyer la valeur booléenne de l'index fourni avec une valeur par défaut si la clé n'est pas trouvée

int getInt(int index)

Renvoyer la valeur entière de l'index fourni : elle invoque la méthode getJsonNumber(index).intValue()

int getInt(int index, int defaultValue)

Renvoyer la valeur entière de l'index fourni avec une valeur par défaut si la clé n'est pas trouvée

JsonArray getJsonArray(int index)

Renvoyer l'instance de type JsonArray encapsulant les données du tableau pour l'index fourni

JsonNumber getJsonNumber(int index)

Renvoyer l'instance de type JsonNumber encapsulant la valeur numérique pour l'index fourni

JsonObject getJsonObject(int index)

Renvoyer l'instance de type JsonObject encapsulant les données de l'objet pour l'index fourni

JsonString getJsonString(int index)

Renvoyer la chaîne de caractères pour l'index fourni

String getString(int index)

Renvoyer la chaîne de caractères pour l'index fourni : elle invoque la méthode getJsonString(index).getString()

String getString(int index, String defaultValue)

Renvoyer la chaîne de caractères pour l'index fourni avec la valeur par défaut si la clé n'est pas trouvée

<T extends JsonValue> List<T> getValuesAs(Class<T> clazz)

Renvoyer une vue sous la forme d'une List typée avec la classe fournie en paramètre

boolean isNull(int index)

Renvoyer un booléen qui précise si la valeur à l'index fourni en paramètre est JsonValue.NULL

 

56.3.2. L'interface JsonReader

L'interface JsonReader permet de lire un document JSON.

Plusieurs méthodes permettent d'obtenir le premier élément du document JSON lu ou de le fermer :

Méthode

Rôle

void close()

Terminer les traitements et libérer les éventuelles ressources

JsonStructure read()

Renvoyer un objet de type JsonArray ou JsonObject selon le contenu du document

JsonObject readObject()

Renvoyer un objet de type JsonObject qui encapsule l'objet du document

JsonArray readArray()

Renvoyer un objet de type JsonArray qui encapsule le tableau du document


Ces méthodes ne doivent être invoquées qu'une seule fois pour une même instance.

La méthode close() doit être invoquée explicitement ou implicitement grâce à une instruction try with ressources de Java 7 pour libérer d'éventuelles ressources.

Pour créer une instance de type JsonReader, il y a deux possibilités :

  • invoquer la méthode createReader() de la classe Json qui est une fabrique pour créer une instance de la classe JsonReader. Elle attend en paramètre le document source à lire sous la forme d'une instance de type InputStream ou Reader.
  • obtenir une instance de type JsonParserFactory en invoquant la méthode Json.createGeneratorFactory() et invoquer la méthode createGenerator() sur cette instance. Cette façon de faire permet de configurer l'instance.
Exemple ( code Java 7 ) :
            String document = "[{\n"
                    + "\"nom\":\"nom1\", \"prenom\": \"prenom1\", \"taille\":175\n"
                    + "},\n"
                    + "{\n"
                    + "\"nom\":\"nom2\", \"prenom\": \"prenom2\",\"taille\": 183\n"
                    + "}\n"
                    + "]";
            try (JsonReader reader = Json.createReader(new StringReader(document))) {
                JsonArray array = reader.readArray();
                JsonObject obj = array.getJsonObject(1);
                String nom = obj.getJsonString("nom").getString();
            }

L'objet de type JsonObject, JsonArray ou JsonStructure encapsule l'élément racine du graphe d'objets créé suite à la lecture. Cet objet peut être utilisé pour parcourir le graphe ou pour écrire sa représentation JSON.

 

56.3.3. Le parcours du modèle objet

Il est possible de parcourir ou d'obtenir un élément particulier du graphe d'objets en utilisant les différentes méthodes des objets qui le compose.

La méthode getValueType() de la classe JsonValue permet de déterminer le type de l'élément en cours de traitement. Il suffit alors de faire un cast vers le type concerné pour avoir accès aux méthodes dédiées de ce type.

Exemple ( code Java 7 ) :
//

...
      String document = "[{\n"
              + "\"nom\":\"nom1\", \"prenom\": \"prenom1\",\"taille\": 175\n"
              + "},\n"
              + "{\n"
              + "\"nom\":\"nom2\", \"prenom\": \"prenom2\",\"taille\": 183\n"
              + "}\n"
              + "]";
      try (JsonReader reader = Json.createReader(new StringReader(document))) {
        JsonArray array = reader.readArray();
        System.out.println("Debut du parcours du modele");
        parcourirModele(array, null, 0);
        System.out.println("Fin du parcours du modele");
      } catch (Exception e) {
        e.printStackTrace();
      }
//

...
  public static void parcourirModele(final JsonValue element, 
    final String cle, final int niveau) {
    String indentation = Strings.repeat("..", niveau);
    int niveauSuivant = niveau+1;
    if (cle != null) {
      System.out.print(indentation+"Key " + cle + ": ");
    }
    switch (element.getValueType()) {
      case OBJECT:
        System.out.println(indentation+"Objet");
        JsonObject object = (JsonObject) element;
        for (String nom : object.keySet()) {
          parcourirModele(object.get(nom), nom, niveauSuivant);
        }
        break;
      case ARRAY:
        System.out.println(indentation+"Tableau");
        JsonArray array = (JsonArray) element;
        for (JsonValue val : array) {
          parcourirModele(val, null, niveauSuivant);
        }
        break;
      case STRING:
        JsonString st = (JsonString) element;
        System.out.println(" String " + st.getString());
        break;
      case NUMBER:
        JsonNumber num = (JsonNumber) element;
        System.out.println(" Nombre " + num.toString());
        break;
      case TRUE:
      case FALSE:
      case NULL:
        System.out.println(" " +element.getValueType().toString());
        break;
    }
  }
Résultat :
Debut du parcours du modele
Tableau
..Objet
....Key
nom: String nom1
....Key
prenom: String prenom1
....Key
taille: Nombre 175
..Objet
....Key
nom: String nom2
....Key
prenom: String prenom2
....Key
taille: Nombre 183
Fin
du parcours du modele

La méthode s'appelle récursivement si l'élément est un JsonArray indépendant ou contenu dans un JsonObject permettant ainsi le parcours de tous les éléments.

La méthode keySet() de la classe JsonObject renvoie une collection des clés qui composent l'objet. La méthode get() de la classe JsonObject permet d'obtenir la valeur pour la clé passée en paramètre.

 

56.3.4. L'interface JsonArrayBuilder

L'interface JsonArrayBuilder définit des méthodes pour faciliter la création d'objets de type JsonArray qui encapsulent un tableau JSON.

Cette interface repose sur le motif de conception builder : elle définit donc plusieurs méthodes pour ajouter des éléments au tableau et pour obtenir l'objet :

Méthode

Rôle

JsonArrayBuilder add(BigDecimal value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder add(BigInteger value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder add(String name, boolean value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder add(double value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder add(int value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder add(JsonArrayBuilder builder)

Ajouter un autre tableau JSON (encapsulé dans une instance de type JsonArrayBuilder) au tableau

JsonArrayBuilder add(JsonObjectBuilder builder)

Ajouter un nouvel objet JSON (encapsulé dans une instance de type JsonObjectBuilder) au tableau

JsonArrayBuilder add(JsonValue value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder add(long value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder add(String value)

Ajouter une nouvelle valeur au tableau

JsonArrayBuilder addNull(String name)

Ajouter une valeur null au tableau

JsonObject build()

Retourner l'instance encapsulant le tableau contenant toutes les valeurs ajoutées


Toutes les surcharges de la méthode add() utilisent le modèle fluent : elles renvoient l'instance elle-même du JsonArrayBuilder ce qui permet de chaîner leurs invocations.

Pour obtenir une instance de type JsonArrayBuilder, il faut utiliser la méthode createArrayBuilder() de la classe Json qui est une fabrique. Par défaut, elle crée un tableau JSON vide et propose des surcharges de la méthode add() pour ajouter des valeurs au document et la méthode build() pour obtenir l'instance de type JsonArrayBuilder correspondante.

Exemple :
        JsonArray jsonArray = Json.createArrayBuilder()
                .add("valeur1")
                .add("valeur2")
                .add("valeur3")
                .build();
Résultat :
["valeur1","valeur2","valeur3"]

 

56.3.5. L'interface JsonObjectBuilder

L'interface JsonObjectBuilder définit des méthodes pour faciliter la création d'un objet de type JsonObject qui encapsule un objet JSON.

Cette interface repose sur le motif de conception builder : elle définit donc plusieurs méthodes pour ajouter des éléments à l'objet et pour obtenir l'objet:

Méthode

Rôle

JsonObjectBuilder add(String name, BigDecimal value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder add(String name, BigInteger value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder add(String name, boolean value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder add(String name, double value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder add(String name, int value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder add(String name, JsonArrayBuilder builder)

Ajouter un nouvel élément dont le nom et le tableau JSON (encapsulé dans une instance de type JsonArrayBuilder) associé sont fournis en paramètres

JsonObjectBuilder add(String name, JsonObjectBuilder builder)

Ajouter un nouvel élément dont le nom et l'objet JSON (encapsulé dans une instance de type JsonObjectBuilder) associé sont fournis en paramètres

JsonObjectBuilder add(String name, JsonValue value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder add(String name, long value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder add(String name, String value)

Ajouter un nouvel élément dont le nom et la valeur sont fournis en paramètres

JsonObjectBuilder addNull(String name)

Ajouter un nouvel élément dont le nom est fourni en paramètre avec la valeur null

JsonObject build()

Retourner l'instance contenant tous les éléments ajoutés


Toutes les surcharges de la méthode add() utilisent le modèle fluent : elles renvoient l'instance elle-même du JsonObjectBuilder ce qui permet de chaîner leurs invocations.

Pour obtenir une instance de type JsonObjectBuilder, il faut utiliser la méthode createObjectBuilder() de la classe Json qui est une fabrique. Par défaut, elle crée un objet JSON vide et propose des surcharges de la méthode add() pour ajouter des éléments et la méthode build() pour obtenir l'instance de type JsonObjectBuilder correspondante.

Exemple :
        JsonObject jsonObj = Json.createObjectBuilder()
                .add("nom", "nom1")
                .add("prenom", "prenom1")
                .add("taille", "175")
                .build();
Résultat :
{"nom":"nom1","prenom":"prenom1","taille":"175"}

L'objet JSON peut être plus complexe en imbriquant différents objets et tableaux.

Exemple :
        JsonObject jsonObj = Json.createObjectBuilder()
                .add("nom", "groupe1") 
                .add("personnes", Json.createArrayBuilder()
                  .add(Json.createObjectBuilder()
                    .add("nom", "nom1")
                    .add("prenom", "prenom1")
                    .add("taille", "175"))
                  .add(Json.createObjectBuilder()
                    .add("nom", "nom1")
                    .add("prenom", "prenom1")
                    .add("taille", "175")))
                .build();
Résultat :
{"nom":"groupe1",
"personnes":[{"nom":"nom1","prenom":"prenom1","taille":"175"},
      {"nom":"nom1","prenom":"prenom1","taille":"175"}]}

 

56.3.6. L'interface JsonWriter

L'interface javax.json.JsonWriter définit des méthodes pour permettre l'envoi dans un flux de caractères d'instances de types JsonObject, JsonArray ou JsonStructure.

Méthode

Rôle

void close()

Fermer le writer et libérer les éventuelles ressources associées

void write(JsonStructure value)

Ecrire l'objet ou le tableau JSON passé en paramètre

void writeArray(JsonArray array)

Ecrire le tableau JSON passé en paramètre

void writeObject(JsonObject object)

Ecrire l'objet JSON passé en paramètre


Pour obtenir une instance de type JsonWriter, il faut soit :

  • invoquer la méthode createWriter() de la classe Json qui est une fabrique pour créer une instance de la classe JsonWriter. Elle attend en paramètre une instance de type InputStream ou Reader
  • obtenir une instance de type JsonWriterFactory en invoquant la méthode Json.createWriterFactory() et invoquer la méthode createWriter() sur cette instance. Cette façon de faire permet de configurer l'instance.
Exemple ( code Java 7 ) :
                JsonObject jsonObj = Json.createObjectBuilder()
                        .add("nom", "nom1")
                        .add("prenom", "prenom1")
                        .add("taille", "175")
                        .build();
                StringWriter stringWriter = new StringWriter();
                try (JsonWriter writer = Json.createWriter(stringWriter)) {
                    writer.writeObject(jsonObj);
                    System.out.println(stringWriter.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }

La méthode close() doit être invoquée explicitement ou implicitement grâce à une instruction try with ressources de Java 7 pour fermer le flux associé.

 

56.3.7. Les interfaces JsonXXXFactory

L'API définit plusieurs interfaces qui définissent des fonctionnalités pour des fabriques d'instances :

  • JsonBuilderFactory : pour créer des instances de type JsonObjectbuilder ou JsonArrayBuilder
  • JsonReaderFactory : pour créer des instances de type JsonReader
  • JsonWriterFactory : pour créer des instances de type JsonWriter

Toutes leurs méthodes sont threads safe. La classe Json propose aussi des méthodes pour créer des instances mais si plusieurs instances d'un même type doivent être créées alors il est préférable d'utiliser la fabrique correspondante.

L'interface JsonBuilderFactory définit les méthodes d'une fabrique permettant de créer des instances de type JsonObjectBuilder et JsonArrayBuilder.

Elle définit plusieurs méthodes :

Méthode

Rôle

JsonArrayBuilder createArrayBuilder()

Créer une instance de type JsonArrayBuilder

JsonObjectBuilder createObjectBuilder()

Créer une instance de type JsonObjectBuilder

Map<String,?> getConfigInUse()

Renvoyer une collection immuable de type Map qui contient les propriétés de configuration utilisées pour créer les instances


Pour obtenir une instance de type JsonBuilderFactory, il faut utiliser la méthode statique createBuilderFactory() de la classe Json.

L'interface JsonReaderFactory définit les méthodes d'une fabrique permettant de créer des instances de type JsonReader.

Elle définit plusieurs méthodes :

Méthode

Rôle

JsonReader createReader(InputStream in)

Créer une instance de type JsonReader sur un flux d'octets

JsonReader createReader(InputStream in, Charset charset)

Créer une instance de type JsonReader sur un flux d'octets en utilisant le jeu de caractères fourni en paramètre

JsonReader createReader(Reader reader)

Créer une instance de type JsonReader sur un flux de type caractères

Map<String,?> getConfigInUse()

Renvoyer une collection immuable de type Map qui contient les propriétés de configuration utilisées pour créer les instances


Pour obtenir une instance de type JsonReaderFactory, il faut utiliser la méthode statique createReaderFactory() de la classe Json.

L'interface JsonReaderFactory définit les méthodes d'une fabrique permettant de créer des instances de type JsonReader.

Elle définit plusieurs méthodes :

Méthode

Rôle

JsonWriter createWriter(OutputStream out)

Créer une instance de type JsonWriter sur un flux d'octets

JsonWriter createWriter(OutputStream out, Charset charset)

Créer une instance de type JsonWriter sur un flux d'octets en utilisant le jeu de caractères fourni en paramètre

JsonWriter createWriter(Writer writer)

Créer une instance de type JsonWriter sur un flux de type caractères

Map<String,?> getConfigInUse()

Renvoyer une collection immuable de type Map qui contient les propriétés de configuration utilisées pour créer les instances


Pour obtenir une instance de type JsonWriterFactory, il faut utiliser la méthode statique createWriterFactory() de la classe Json.

 

 


[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

78 commentaires Donner une note à l´article (5)

 

Copyright (C) 1999-2022 Jean-Michel DOUDOUX. Vous pouvez copier, redistribuer et/ou modifier ce document selon les termes de la Licence de Documentation Libre GNU, Version 1.1 ou toute autre version ultérieure publiée par la Free Software Foundation; les Sections Invariantes étant constitués du chapitre Préambule, aucun Texte de Première de Couverture, et aucun Texte de Quatrième de Couverture. Une copie de la licence est incluse dans la section GNU FreeDocumentation Licence. La version la plus récente de cette licence est disponible à l'adresse : GNU Free Documentation Licence.