gson 在java中查询JSONObject

k75qkfdt  于 7个月前  发布在  Java
关注(0)|答案(7)|浏览(75)

我想知道是否有一个Java库可以查询JSONObject。更深入地说,我正在寻找类似于:

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


写起来和读起来都不容易。有没有更快的?

qni6mghb

qni6mghb1#

我刚刚意外地发现了一个非常有趣的项目:JSON Path
JsonPath之于JSON就像XPATH之于XML,是一种提取给定文档的一部分的简单方法。
有了这个库,你可以更容易地做你所要求的,然后我以前的建议:

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

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

字符串
希望这也能有所帮助。

hkmswyz6

hkmswyz62#

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

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

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

编辑(2015年8月)

实际上,现在(从Jackson2.3开始)Jackson支持JSON Pointer表达式。所以你可以选择用途:

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

wsewodh2

wsewodh23#

首先,我建议考虑JSON对象绑定。
但是如果你得到任意的JSON对象,并且你想用你描述的方式处理它们,我建议合并Jackson JSON processor沿着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

字符串

ebdffaop

ebdffaop4#

你可以使用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"));

字符串

fsi0uk1n

fsi0uk1n5#

另一个也适用于当前Java版本(21)并提供validation functionality的解决方案是Burningwave JSON库:

String json = "{ data: { data2 : { value : 'hello'}}}";
Facade facade = Facade.create(new ObjectMapper());
ObjectHandler jsonObjectHandler = facade.newObjectHandler(json , Map.class);
String value = jsonObjectHandler.newValueFinder().findFirstForPathEndsWith("value");

字符串

ttcibm8c

ttcibm8c6#

我觉得不可能。
考虑一个java类

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

class Subject {
    String name;
}

字符串
这里如果我们想访问主题名,

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


我们不能直接访问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类中所做的那样创建单独的类。

csga3l58

csga3l587#

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

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

字符串
在JSON的1.1.4版本中,JsonStructure接口(由JsonObjectJsonArray实现)也有很好的补充,即getValue(String jsonPointer)。所以这一切都归结为这个简单的一行程序:

System.out.println(jsonObject.getValue("/data/data2/value"));

相关问题