web-dev-qa-db-ja.com

javaでJSONObjectをクエリする

JSONObjectをクエリできるJava libreryがどこかに存在するかどうか疑問に思っていました。より深く、次のようなものを探しています:

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);

出力として「hello」を取得する予定です。

今では、私が見つけた最速の方法はGsonを使用することです:

jsonObject.getAsJsonObject("data").getAsJsonObject().get("data2").getAsJsonObject("value").getAsString();

実際には、読み書きは簡単ではありません。もっと速いものはありますか?

36
Pamput

私は予想外に非常に興味深いプロジェクトを見つけました: JSON Path

JsonPathはJSONに対して、XPATHはXMLに対して、特定のドキュメントの一部を抽出する簡単な方法です。

このライブラリを使用すると、リクエストをさらに簡単に行うことができます。その後、私の以前の提案:

String hello = JsonPath.read(json, "$.data.data2.value");

System.out.println(hello); //prints hello

これが参考になることを願っています。

39
n1ckolas

まったく同じではありませんが、ジャクソンにはGsonに似たツリーモデル表現があります。

JsonNode root = objectMapper.readTree(jsonInput);
return root.get("data").get("data2").get("value").asText();

順を追ってトラバースする必要があります。

[〜#〜] edit [〜#〜](2015年8月)

実際には(Jackson 2.3以降) JSON Pointer 式がJacksonでサポートされています。したがって、代わりに使用することができます:

return root.at("/data/data2/value").asText();
19
StaxMan

まず、JSONオブジェクトバインディングを検討することをお勧めします。

ただし、任意のJSONオブジェクトを取得し、説明した方法で処理したい場合は、 Jackson JSONプロセッサ とApacheの Commons Beanutils を組み合わせることをお勧めします。

考え方は次のとおりです。デフォルトでは、JacksonはすべてのJSONをJava.util.Mapインスタンスとして処理します。一方、Commons Beanutilsは、配列やマップサポートを含むオブジェクトのプロパティアクセスを簡素化します。

したがって、次のように使用できます。

//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
n1ckolas

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"));
3
GSK

仕方ないと思います。

Javaクラスを検討する

class Student {
    Subject subject = new Subject();
}

class Subject {
    String name;
}

ここでサブジェクト名にアクセスする場合は、

Student stud = new Student();
stud.subject.name; 

名前に直接アクセスできない場合は、正しいサブジェクト名を取得できません。ここみたいに:

jsonObject.getAsJsonObject("data")
          .getAsJsonObject()
          .get("data2")
          .getAsJsonObject("value")
          .getAsString();

Javaオブジェクトのように同じものを使用したい場合は、

ClassName classObject = new Gson().fromJson(JsonString, ClassName.class);

ClassNameには、jsonstringと一致するすべてのフィールドが必要です。 jsonobject内にjsonobjectがある場合は、StudentクラスとSubjectクラスで行うように、別個のクラスを作成する必要があります。

1
Parvathy