[英]Jackson parse tree response
I want to parse google nearby places response, an item have this format : 我想解析谷歌附近的地方响应,一个项目有这种格式:
"geometry" : {
"location" : {
"lat" : 75.22404,
"lng" : 57.42276
},
"viewport" : {
"northeast" : {
"lat" : 95.2353532,
"lng" : 75.4427513
},
"southwest" : {
"lat" : 55.207256,
"lng" : 45.4045009
}
}
},
"vicinity" : "something"
But I want to parse this using only one object something like that : 但是我想用一个像这样的对象来解析它:
public class NearbyPlace extends BaseResponse {
@JsonProperty("how to access geometry->lat ?")
private double latitude;
@JsonProperty("how to access geometry->lng ?")
private double longitude;
@JsonProperty("vicinity")
private String vicinity;
}
The problem is how to access "lat" and "lng" in "geometry" directly from NearbyPlace class without creating another classes for each node ? 问题是如何直接从NearbyPlace类访问“几何”中的“lat”和“lng”而不为每个节点创建另一个类?
You can use a combination of readTree()
and treeToValue()
: 您可以使用
readTree()
和treeToValue()
:
final String placesResponse = "...";
final ObjectMapper om;
NearbyPlace place = null;
final JsonNode placesNode = om.readTree(placesResponse);
final JsonNode locationNode = placesNode.findPath("geometry").findPath("location");
if (! locationNode.isMissingNode()) {
place = om.treeToValue(locationNode, NearbyPlace.class);
}
However, since vicinity
kept outside of the inner geometry class, you still need to set that value manually. 但是,由于
vicinity
保持在内部几何类之外,您仍需要手动设置该值。 JsonNode
has the necessary methods: JsonNode
有必要的方法:
final JsonNode vicinityNode = placesNode.findPath("vicinity");
if (vicinityNode.isTextual()) {
place.vicinity = vicinityNode.textValue();
}
Since you will end up with a collection of NearbyPlace
s, you may be best off just manually traversing the JsonNode
. 由于您最终会得到一个
NearbyPlace
集合, NearbyPlace
您最好只需手动遍历JsonNode
。 Otherwise you're talking about overriding deserialization for collections, or writing a deserializer that is likely to get nasty. 否则你谈论的是对集合的重新反序列化,或者编写一个可能令人讨厌的反序列化器。
The example below is recursive. 下面的示例是递归的。 Recursion in Java is bad (for now), but fun to write.
Java中的递归很糟糕 (现在),但编写很有趣。 In a production app I'd recommend a loop.
在生产应用程序中,我建议循环。
@Test
public void testNearbyPlaceDeserialization() throws Exception {
JsonNode jsonNode = objectMapper.readTree(new File("input.json"));
// or objectMapper.readValue(resultString, JsonNode.class);
ImmutableList<NearbyPlace> nearbyPlaces = readLatLng(jsonNode,
jsonNode.get("vicinity").asText(null),
ImmutableList.builder());
System.out.println(nearbyPlaces);
}
private static ImmutableList<NearbyPlace> readLatLng(JsonNode jsonNode,
String vicinity,
ImmutableList.Builder<NearbyPlace> placeBuilder) {
JsonNode latNode = jsonNode.get("lat");
JsonNode lngNode = jsonNode.get("lng");
if (latNode != null && lngNode != null) {
placeBuilder.add(NearbyPlace.builder()
.setLatitude(latNode.asDouble())
.setLongitude(lngNode.asDouble())
.setVicinity(vicinity)
.build());
} else {
jsonNode.elements().forEachRemaining((element) -> {
readLatLng(element, vicinity, placeBuilder);
});
}
return placeBuilder.build();
}
This will return a list of 3 NearbyPlace
s. 这将返回3个
NearbyPlace
的列表。
The easiest solution I can think of is to use the @JsonCreator
annotation on your NearbyPlace
class' constructor: 我能想到的最简单的解决方案是在您的
NearbyPlace
类的构造函数上使用@JsonCreator
注释:
public class NearbyPlace extends BaseResponse {
private double latitude;
private double longitude;
@JsonProperty("vicinity")
private String vicinity;
@JsonCreator
public NearbyPlace(Map<String, Object> delegate) {
super();
this.latitude = (Double) delegate.get("geometry").get("location").get("lat");
this.latitude = (Double) delegate.get("geometry").get("location").get("lng");
}
}
You might want to add some checks against null
in case the incoming JSON lacks some nested object, ie geometry
or location
. 如果传入的JSON缺少某些嵌套对象(即
geometry
或location
,您可能希望对null
添加一些检查。
Please refer to Jackson annotations documentation for further details. 有关更多详细信息,请参阅Jackson注释文档 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.