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?

31
demandé sur Pamput 2013-03-15 14:20:28

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.

34
répondu n1ckolas 2015-10-23 19:16:27

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();
18
répondu StaxMan 2015-08-11 21:22:28

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
16
répondu n1ckolas 2013-03-15 10:38:31

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.

1
répondu Parvathy 2017-01-23 12:31:58

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"));
0
répondu GSK 2018-07-14 01:03:19