Interroger un JSONObject en java
Je me demandais si quelque part il existe une bibliothèque java capable d'interroger un JSONObject. Plus en profondeur, je cherche quelque chose comme:
String json = "{ data: { data2 : { value : 'hello'}}}";
...
// Somehow we managed to convert json to jsonObject
...
String result = jsonObject.getAsString("data.data2.value");
System.out.println(result);
Je m'attends à obtenir "hello" en sortie.
Maintenant, le moyen le plus rapide que j'ai trouvé est d'utiliser Gson:
jsonObject.getAsJsonObject("data").getAsJsonObject().get("data2").getAsJsonObject("value").getAsString();
Ce n'est pas vraiment facile à écrire et à lire. Est-il quelque chose de plus rapide?
5 réponses
Je viens de trouver de façon inattendue un projet très intéressant: JSON Path
JsonPath est à JSON ce que XPATH est à XML, un moyen simple d'extraire des parties d'un document donné.
Avec cette bibliothèque, vous pouvez faire ce que vous demandez encore plus facilement, alors ma suggestion précédente:
String hello = JsonPath.read(json, "$.data.data2.value");
System.out.println(hello); //prints hello
J'espère que cela pourrait être utile non plus.
Bien que pas exactement la même chose, Jackson a une représentation de modèle D'arbre similaire à Gson:
JsonNode root = objectMapper.readTree(jsonInput);
return root.get("data").get("data2").get("value").asText();
Vous devez donc le parcourir étape par étape.
Modifier (août 2015)
Il existe actuellement (depuis Jackson 2.3) un support pour les expressions pointeur JSON avec Jackson. Donc, vous pouvez également utiliser:
return root.at("/data/data2/value").asText();
Tout d'abord, je recommande de considérer la liaison d'objet JSON.
Mais dans le cas où vous obtenez des objets JSON arbitraires et que vous souhaitez les traiter de la manière que vous avez décrite, je suggère de combiner Jackson JSON processor avec Apache Commons Beanutils.
L'idée est la suivante: Jackson traite par défaut toutes les instances JSON en tant que java.util.Map
, tandis que Commons beanutils simplifie L'accès aux propriétés pour les objets, y compris les tableaux et la carte soutien.
Donc, vous pouvez l'utiliser quelque chose comme ceci:
//actually it is a Map instance with maps-fields within
Object jsonObj = objectMapper.readValue(json, Object.class);
Object hello = PropertyUtils.getProperty(jsonObj, "data.data2.value")
System.out.println(hello); //prints hello
Je ne pense pas.
Considérons une classe java
class Student {
Subject subject = new Subject();
}
class Subject {
String name;
}
Ici, si nous voulons accéder au nom du sujet, alors
Student stud = new Student();
stud.subject.name;
Nous ne pouvons pas accéder directement au nom, si c'est le cas, nous n'obtiendrons pas le nom du sujet correct. Comme ici:
jsonObject.getAsJsonObject("data")
.getAsJsonObject()
.get("data2")
.getAsJsonObject("value")
.getAsString();
Si vous voulez utiliser le même objet java, Utilisez
ClassName classObject = new Gson().fromJson(JsonString, ClassName.class);
ClassName doit avoir tous les champs pour correspondre à jsonstring. Si vous avez un jsonobject dans un jsonobject alors vous devez créer une classe séparée comme je le fais dans Student et Subject classe.
Vous pouvez utiliser org.json
String json = "{ data: { data2 : { value : 'hello'}}}";
org.json.JSONObject obj = new org.json.JSONObject(json);
System.out.println(obj.query("/data/data2/value"));