遍历 JsonPath 数组的策略

Posted

技术标签:

【中文标题】遍历 JsonPath 数组的策略【英文标题】:Strategies for iterating through JsonPath array 【发布时间】:2017-03-23 21:02:33 【问题描述】:

我今天才开始探索 JsonPath。我想探索的不仅仅是可以用它做什么,还想探索一些有效的策略。

例如,假设我必须遍历包含在 json 字符串中的一个元素中的数组。

我正在使用来自https://github.com/jayway/JsonPath#path-examples 的“商店”示例。

要获取书籍列表本身,我想我可以这样做:

List<?> allBooks    = JsonPath.<List<?>>read(context, "$.store.book");

这样想有意义吗?

这是我不确定的迭代逻辑。

我原以为我可以定义一个“书”pojo,然后做这样的事情:

    for (int ctr = 0; ctr < allBooks.size(); ++ ctr) 
        Book book   = JsonPath.<Book>read(context, ".[" + ctr + "]");
        System.out.println("book[" + book + "]");
    

但是,这不起作用。此时的“read”方法返回一个JSONArray

https://github.com/jayway/JsonPath#what-is-returned-when 的代码示例的最后一行与我正在查看的内容接近,但这需要在每次迭代中解析 json。似乎“DocumentContext”类有“read”方法可以接受类型参数,但不能接受“JsonPath”。

有哪些合理的策略来导航这样的事情?

【问题讨论】:

【参考方案1】:

JSON 路径只会返回一个Maps 列表,正如你已经看到的那样。您需要一种方法来告诉它如何将这些值映射到对象 - 为此您需要自定义配置。还有其他提供商,例如 Gson 等,但我只使用过 Jackson。

Configuration configuration = Configuration
        .builder()
        .jsonProvider(new JacksonJsonProvider())
        .mappingProvider(new JacksonMappingProvider())
        .build();

第二步是用TypeRef指定泛型类型信息,并在读取标签时传递。

List<Book> allBooks = JsonPath.using(configuration)
        .parse(context)
        .read("$.store.book", new TypeRef<List<Book>>() );

因此,您会得到一个很好的 Book 对象列表。

【讨论】:

这很好用,但我注意到 JsonPath (github.com/jayway/JsonPath) 的主文档页面甚至没有提到 TypeRef。我猜使用 TypeRef 就像使用 Class 对象一样,但它有效地传达了泛型类型信息。是时候解决问题了。

以上是关于遍历 JsonPath 数组的策略的主要内容,如果未能解决你的问题,请参考以下文章

JsonPath —— JSON 解析神器

使用jsonpath提取复杂响应中的数组及其他字段

使用 jsonpath_ng 检查数组中的元素失败并出现 JsonPathParseError

数组的Java JsonPath长度

jsonpath的使用

使用JSONPath