繁体   English   中英

使用 Jackson 解析 Java 中的 JSON 子集

[英]Parsing a subset of JSON in Java using Jackson

给定 Json,是否可以使用 Jackson 仅解析消息的一部分? 假设我感兴趣的数据被埋在一个深层次的字段中,我根本不关心为每个类创建 DTO 类。

鉴于一个非常简化的场景,我想在不了解之前的结构的情况下对 Telephone 类进行建模:

...{
  "firstName": "John",
  "lastName" : "doe",
  "age"      : 26,
  "address"  : {
    "streetAddress": "naist street",
    "city"         : "Nara",
    "postalCode"   : "630-0192"
  },
  "phoneNumbers": [
    {
      "type"  : "iPhone",
      "number": "0123-4567-8888"
    },
    {
      "type"  : "home",
      "number": "0123-4567-8910"
    }
  ]
}....

我正在考虑使用 json-path 以及反序列化我感兴趣的部分。 一些伪:

List<Telephone> phoneNrs = parse(".my.deep.structure.persons.phoneNumbers", List<Telephone.class>);
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree("... your JSON ...");

使用JsonNode对象,您可以调用get("my").get("deep").get("structure")来获取您想要的节点。

一旦您掌握了该节点,只需调用mapper.treeToValue(myDeepJsonNode, Telephone[].class)获得Telephone数组。 您也可以使用TypeReference获取列表。

要获得深层JsonNode您还可以使用findValuefindPath方法。

Javadoc: https : //fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/JsonNode.html

您可以使用JsonPath库。 使用这个库,您可以将您的 JsonPath 输出直接映射到 POJO 中。

伪:

List<Telephone> phoneNrs = JsonPath.parse(json).read("$.my.deep.structure.persons.phoneNumbers", List.class);

是的,您在伪代码中提到的方式是可能的。 “phoneNumbers”是一个键,返回的值可以传递给杰克逊反序列化。

如果响应是一组地图,那么您可以遍历每个地图并使用yourResponseAsJSONObject.get('phoneNumbers')方法获取值并将其传递给 Jackson

或使用@dimas 提到的 JsonPath

要使用 Jackson 有效地执行此操作,请通过 JsonParser 类 ( http://fasterxml.github.io/jackson-core/javadoc/2.5/com/fasterxml/jackson/core/JsonParser.html ) 使用 Streaming API。

这种方法不会分配额外的内存,也不会产生为所有跳过的数据反序列化值的成本。 由于与使用 Jackson 的 ObjectMapper 相比,代码会更长且更难阅读,因此只有在分析过程中分析显示不可接受的 GC 活动或 CPU 使用率时才执行此操作。

您可以跳过所有您不感兴趣的节点,直到您按下“phoneNumbers”键。 然后您可以调用readValueAs函数来反序列化电话号码字典数组,例如readValueAs(new TypeReference<MyPhoneNumberType[]>())

另见:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM