48

我想知道某个地方是否存在能够查询 JSONObject 的 java 库。更深入地,我正在寻找类似的东西:

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

我希望得到“你好”作为输出。

到目前为止,我发现最快的方法是使用 Gson:

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

写和读实际上并不容易。有什么更快的吗?

4

6 回答 6

48

我刚刚意外发现了一个非常有趣的项目:JSON Path

JsonPath 之于 JSON 就像 XPATH 之于 XML,这是一种提取给定文档部分的简单方法。

有了这个库,您可以更轻松地完成您的要求,然后是我之前的建议:

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

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

希望这也可能有所帮助。

于 2013-03-21T15:16:48.590 回答
28

虽然不完全相同,但 Jackson 具有类似于 Gson 的树模型表示:

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

所以你需要一步一步地遍历它。

编辑(2015 年 8 月)

实际上,现在(从 Jackson 2.3 开始)支持 Jackson 的JSON 指针表达式。所以你可以选择使用:

return root.at("/data/data2/value").asText();
于 2013-03-16T18:46:56.450 回答
17

首先,我建议考虑 JSON 对象绑定。

但是,如果您获得任意 JSON 对象并且希望以您描述的方式处理它们,我建议将Jackson JSON 处理器与 Apache 的Commons Beanutils结合起来。

想法如下:Jackson 默认将所有 JSON 处理为java.util.Map实例,同时 Commons Beanutils 简化了对象的属性访问,包括数组和 Map 支持。

所以你可以像这样使用它:

//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
于 2013-03-15T10:38:31.643 回答
5

您可以使用 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"));
于 2018-07-12T16:12:58.430 回答
1

我觉得没办法。

考虑一个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 类中那样创建单独的类。

于 2013-03-15T10:36:21.567 回答
1

使用 Java JSON API 1.1.x (javax.json) 可以利用新的JavaPointer接口。实现此接口的实例在某种程度上可以被认为是一种 XPath 表达式模拟(有关详细信息,请参阅RFC-6901)。所以在你的情况下,你可以这样写:

import javax.json.*;
//...
var jp = Json.createPointer("/data/data2/value");
System.out.println(jp.getValue(jsonObject));

在 JSON 的 1.1.4 版本中,还对JsonStructure接口(由JsonObject和实现JsonArray)做了很好的补充,即getValue(String jsonPointer). 所以这一切都归结为这个简单的单行:

System.out.println(jsonObject.getValue("/data/data2/value"));
于 2020-07-16T18:20:47.507 回答