Recherche…


Introduction

JSON (JavaScript Object Notation) est un format d'échange de données léger, indépendant du langage et basé sur le langage, facile à lire et à écrire pour les utilisateurs et les ordinateurs. JSON peut représenter deux types structurés: les objets et les tableaux. JSON est souvent utilisé dans les applications Ajax, les configurations, les bases de données et les services Web RESTful. L'API Java pour le traitement JSON fournit des API portables pour analyser, générer, transformer et interroger JSON.

Remarques

Cet exemple se concentre sur l'analyse et la création de JSON en Java en utilisant diverses bibliothèques telles que la bibliothèque Google Gson , Jackson Object Mapper, etc.

Des exemples utilisant d'autres bibliothèques peuvent être trouvés ici: Comment analyser JSON en Java

Codage des données en tant que JSON

Si vous devez créer un objet JSONObject et y insérer des données, considérez l'exemple suivant:

// Create a new javax.json.JSONObject instance.
JSONObject first = new JSONObject();

first.put("foo", "bar");
first.put("temperature", 21.5);
first.put("year", 2016);

// Add a second object.
JSONObject second = new JSONObject();
second.put("Hello", "world");
first.put("message", second);

// Create a new JSONArray with some values
JSONArray someMonths = new JSONArray(new String[] { "January", "February" });
someMonths.put("March");
// Add another month as the fifth element, leaving the 4th element unset.
someMonths.put(4, "May");

// Add the array to our object
object.put("months", someMonths);

// Encode
String json = object.toString();

// An exercise for the reader: Add pretty-printing!
/* {
       "foo":"bar",
       "temperature":21.5,
       "year":2016,
       "message":{"Hello":"world"},
       "months":["January","February","March",null,"May"]
   }
*/

Décodage des données JSON

Si vous avez besoin d'obtenir des données à partir d'un objet JSONObject , JSONObject l'exemple suivant:

String json = "{\"foo\":\"bar\",\"temperature\":21.5,\"year\":2016,\"message\":{\"Hello\":\"world\"},\"months\":[\"January\",\"February\",\"March\",null,\"May\"]}";

// Decode the JSON-encoded string
JSONObject object = new JSONObject(json);

// Retrieve some values
String foo = object.getString("foo");
double temperature = object.getDouble("temperature");
int year = object.getInt("year");

// Retrieve another object
JSONObject secondary = object.getJSONObject("message");
String world = secondary.getString("Hello");

// Retrieve an array
JSONArray someMonths = object.getJSONArray("months");
// Get some values from the array
int nMonths = someMonths.length();
String february = someMonths.getString(1);

méthodes optXXX vs getXXX

JSONObject et JSONArray ont quelques méthodes très utiles pour gérer la possibilité qu'une valeur que vous essayez d'obtenir n'existe pas ou soit d'un autre type.

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

// For existing properties of the correct type, there is no difference
obj.getString("foo");        // returns "bar"
obj.optString("foo");        // returns "bar"
obj.optString("foo", "tux"); // returns "bar"

// However, if a value cannot be coerced to the required type, the behavior differs
obj.getInt("foo");      // throws JSONException
obj.optInt("foo");      // returns 0
obj.optInt("foo", 123); // returns 123

// Same if a property does not exist
obj.getString("undefined");        // throws JSONException
obj.optString("undefined");        // returns ""
obj.optString("undefined", "tux"); // returns "tux"

Les mêmes règles s'appliquent aux méthodes getXXX / optXXX de JSONArray .

Objet à JSON (bibliothèque Gson)

Supposons que vous avez une classe appelée Person avec juste le name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Code:

Gson g = new Gson();

Person person = new Person("John");
System.out.println(g.toJson(person)); // {"name":"John"}

Bien sûr, le pot de Gson doit être sur le chemin de classe .

JSON à objet (bibliothèque Gson)

Supposons que vous avez une classe appelée Person avec juste le name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Code:

Gson gson = new Gson();
String json = "{\"name\": \"John\"}";

Person person = gson.fromJson(json, Person.class);
System.out.println(person.name); //John

Vous devez avoir la bibliothèque gson dans votre classpath.

Extraire un seul élément de JSON

String json = "{\"name\": \"John\", \"age\":21}";

JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();

System.out.println(jsonObject.get("name").getAsString()); //John
System.out.println(jsonObject.get("age").getAsInt()); //21

Utilisation de Jackson Object Mapper

Modèle Pojo

public class Model {
    private String firstName;
    private String lastName;
    private int age;
    /* Getters and setters not shown for brevity */        
}

Exemple: chaîne à objet

Model outputObject = objectMapper.readValue(
     "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}",
     Model.class);
System.out.println(outputObject.getFirstName());
//result: John

Exemple: objet à chaîne

String jsonString = objectMapper.writeValueAsString(inputObject));
//result: {"firstName":"John","lastName":"Doe","age":23}

Détails

Déclaration d'importation nécessaire:

import com.fasterxml.jackson.databind.ObjectMapper;

Maven dépendance: jackson-databind

ObjectMapper

//creating one
ObjectMapper objectMapper = new ObjectMapper();
  • ObjectMapper est threadsafe
  • recommandé: avoir une instance partagée et statique

Désérialisation:

<T> T readValue(String content, Class<T> valueType)  
  • valueType doit être spécifié - le retour sera de ce type
  • Jette
    • IOException - en cas de problème d'E / S de bas niveau
    • JsonParseException - si l'entrée sous-jacente contient un contenu non valide
    • JsonMappingException - si la structure JSON en entrée ne correspond pas à la structure de l'objet

Exemple d'utilisation (jsonString est la chaîne d'entrée):

Model fromJson = objectMapper.readValue(jsonString, Model.class);

Méthode de sérialisation:

String writeValueAsString (valeur d'objet)

  • Jette
    • JsonProcessingException en cas d'erreur
    • Note: avant la version 2.1, la clause throws incluait IOException; 2.1 l'a enlevé.

Itération JSON

JSONObject sur les propriétés JSONObject

JSONObject obj = new JSONObject("{\"isMarried\":\"true\", \"name\":\"Nikita\", \"age\":\"30\"}");
Iterator<String> keys = obj.keys();//all keys: isMarried, name & age
while (keys.hasNext()) {                      //as long as there is another key
      String key = keys.next();               //get next key 
      Object value = obj.get(key);            //get next value by key
      System.out.println(key + " : " + value);//print key : value
}

JSONArray sur les valeurs JSONArray

JSONArray arr = new JSONArray();        //Initialize an empty array
//push (append) some values in:
arr.put("Stack");
arr.put("Over");
arr.put("Flow");
for (int i = 0; i < arr.length(); i++) {//iterate over all values
    Object value = arr.get(i);          //get value
    System.out.println(value);          //print each value
}

JSON Builder - méthodes de chaînage

Vous pouvez utiliser le chaînage de méthode tout en travaillant avec JSONObject et JSONArray .

Exemple JSONObject

JSONObject obj = new JSONObject();//Initialize an empty JSON object 
//Before: {}
obj.put("name","Nikita").put("age","30").put("isMarried","true");
//After: {"name":"Nikita","age":30,"isMarried":true}

JSONArray

JSONArray arr = new JSONArray();//Initialize an empty array
//Before: []
arr.put("Stack").put("Over").put("Flow");
//After: ["Stack","Over","Flow"]

JSONObject.NULL

Si vous devez ajouter une propriété avec une valeur null , vous devez utiliser le JSONObject.NULL final statique prédéfini et non la référence null Java standard.

JSONObject.NULL est une valeur sentinelle utilisée pour définir explicitement une propriété avec une valeur vide.

JSONObject obj = new JSONObject();
obj.put("some", JSONObject.NULL);   //Creates: {"some":null}
System.out.println(obj.get("some"));//prints: null

Remarque

JSONObject.NULL.equals(null); //returns true

Ce qui constitue une violation manifeste du contrat Java.equals() :

Pour toute valeur de référence non nulle x, x.equals (null) doit renvoyer false

JsonArray to Java List (Bibliothèque Gson)

Voici un simple JsonArray que vous souhaitez convertir en Java ArrayList :

{
    "list": [
                "Test_String_1",
                "Test_String_2"
            ] 
}

JsonArray maintenant la liste ' JsonArray ' à la méthode suivante qui renvoie une liste de ArrayList Java correspondante:

public ArrayList<String> getListString(String jsonList){
    Type listType = new TypeToken<List<String>>() {}.getType();
    //make sure the name 'list' matches the name of 'JsonArray' in your 'Json'.
    ArrayList<String> list = new Gson().fromJson(jsonList, listType);    
    return list;
}

Vous devez ajouter la dépendance POM.xml suivante à votre fichier POM.xml :

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.7</version>
</dependency>

Ou vous devriez avoir le com.google.code.gson:gson:jar:<version> jar com.google.code.gson:gson:jar:<version> dans votre classpath.

Désérialiser la collection JSON à la collection d'objets à l'aide de Jackson

Supposons que vous ayez une classe de pojo Person

public class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Et vous voulez l'analyser dans un tableau JSON ou une carte d'objets Person. En raison de l'effacement du type, vous ne pouvez pas construire directement les classes de List<Person> et Map<String, Person> (et donc les utiliser pour désérialiser JSON) . Pour surmonter cette limitation, jackson propose deux approches: TypeFactory et TypeReference .

TypeFactory

L'approche adoptée ici consiste à utiliser une fabrique (et sa fonction d'utilitaire statique) pour créer votre type pour vous. Les paramètres pris en compte sont la collection que vous souhaitez utiliser (liste, ensemble, etc.) et la classe que vous souhaitez stocker dans cette collection.

TypeReference

L'approche par référence de type semble plus simple car elle vous permet d'économiser un peu de saisie et est plus propre. TypeReference accepte un paramètre de type, où vous passez le type souhaité List<Person> . Vous instanciez simplement cet objet TypeReference et l'utilisez comme conteneur de type.

Voyons maintenant comment désérialiser réellement votre JSON dans un objet Java. Si votre JSON est formaté en tant que tableau, vous pouvez le désérialiser en tant que liste. S'il existe une structure imbriquée plus complexe, vous souhaiterez désérialiser une carte. Nous examinerons des exemples des deux.

Désérialisation du tableau JSON

String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"

Approche TypeFactory

CollectionType listType = 
    factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);

Approche TypeReference

TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);

Désérialisation de la carte JSON

String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"

Approche TypeFactory

CollectionType mapType = 
    factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);

Approche TypeReference

TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);

Détails

Déclaration d'importation utilisée:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

Instances utilisées:

ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();

Remarque

Bien TypeReference approche TypeReference semble meilleure, elle présente plusieurs inconvénients:

  1. TypeReference doit être instancié à l'aide d'une classe anonyme
  2. Vous devez fournir une explication générique

Si vous ne le faites pas, vous risquez de perdre l'argument de type générique qui entraînera une défaillance de la désérialisation.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow