Java Language
JSON en Java
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:
-
TypeReference
doit être instancié à l'aide d'une classe anonyme - 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.