使用Jackson从JSON数组中检索字符串

13
我找到了几个接近我尝试的解决方案的答案,但还不足以让我成功。我有一堆JSON数据,看起来像这个例子(实际上要深入几个级别,并且在我想要访问的级别上有数百个项目):{"query":{"pages":{"links":[{"word":"bobsyeruncle","code":4},{"word":"easyaspie","code":3}]}}}。我无法更改格式,它是别人的API。我不需要很多这个数据;事实上,我只想要类似于 ["bobsyeruncle", "easyaspie"] 的数组(或List或其他类型)。
我用一个简单版本的JSON进行了实验,它没有数组,并且能够使用rootNode.get("query").get("pages") ...方法轻松访问单个字符串,如https://stackoverflow.com/questions/338586/a-better-java-json-library/338608#338608所述。但是我无法通过这种方式访问数组。我在这里找到的大部分答案都假定我想创建一个包括“word”和“code”的POJO链接,但实际上我并不需要这样。为了访问我想要的字符串,是否有必要创建类似于包含“word”和“code”的“Links”列表,然后忽略“code”?这似乎不对。
(此外,如果有人能够将我指向介于JacksonInFiveMinutes教程和整个javadoc之间的文档/教程,那肯定会有所帮助。)
我认为这个方法可行!
            String theJsonString = "{\"query\":{\"pages\":{\"links\":"
                + "[{\"word\":\"bobsyeruncle\"},{\"word\":\"easyaspie\"}]}}}";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(theJsonString);
        JsonNode interestingObjectNode = rootNode.path("query").path("pages").path("links");
        for (int i = 0; i < interestingObjectNode.size(); i ++) {
            System.out.println(interestingObjectNode.get(i).path("word").asText());
        }
2个回答

10

或许这篇博客文章可以帮助你:使用Jackson遍历JSON树

我不确定你遇到了什么具体的问题,但需要注意的一点是,要遍历JSON数组时需要传递索引值而非名称。因此,当你想要获取一个键值对时可以使用 objectNode.get("key"),但在遍历数组时则应该使用 arrayNode.get(0)。如果你想做“缺失”项的容错处理,也可以使用 arrayNode.path(0) (同样适用于JSON对象)。

同时,请记住你可以在JSON树(JsonNode)和POJO之间相互转换;ObjectMapper提供了多种转换方法(convertValue()、readAsTree()、treeToValue()、valueToTree()),所以可以在某些部分使用数据绑定,而在其他部分使用树模型;有时将子树绑定为POJO,有时只需使用数据绑定高层级并使用树模型访问子树。这是一种非常强大的方式,但也需要一些时间去适应。

希望这有所帮助!


我删除了之前的评论——最终我到达了目的地,上面放了一些代码,以防有人发现这个问题。 - umbraphile
安全?在那个Jackson使用中,“安全”是什么意思?@StaxMan - gumuruh
安全的意思是,如果您使用“get”,并且没有匹配的节点,则返回null,并且必须进行检查。但是使用“path”,将返回一个虚拟的“缺失节点”,因此不需要进行null检查。 - StaxMan

1
在Google的GSON中,如果您创建一个缺少某些属性的POJO,则相应的JSON将被忽略。它只填充那些具有匹配名称的属性。为什么不创建一个像这样的类:
Query{
Pages{
Word[] Links;
}
}

Word{
String word;
String code;
}

然后使用LambdaJ来避免编写所有循环以获取单词?

如果这不够吸引人,请在这里尝试JSONPath

许多文档数据库(如MongoDB和RavenDB等)使用JSON作为其存储格式。查询复杂的JSON已经内置在它们中了,使用它们正在使用的相同库。


1
请在评论中解释为什么您给出了负面评价?如果是因为代码的问题 - 显然这只是一个伪代码,用于解释各种POJO类的组成。 - Zasz
原始问题表明不希望使用POJO定义,因此可能只需改进措辞以建议仍考虑数据绑定?(同样适用于使用jackson vs gson) - StaxMan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接