[英]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
您还可以使用findValue
和findPath
方法。
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.