【问题标题】:Jackson parse tree response杰克逊解析树响应
【发布时间】:2015-09-27 09:34:49
【问题描述】:

我想解析谷歌附近的地方响应,一个项目有这种格式:

         "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"

但我想只使用一个类似的对象来解析它:

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;
}

问题是如何直接从 NearbyPlace 类中访问“几何”中的“lat”和“lng”而不为每个节点创建另一个类?

【问题讨论】:

  • 不应该有收藏吗? NearbyPlaces 的集合或lattittudes 和longitudes 内部NearbyPlaces 的集合?
  • NearbyPlace 是收藏中的一项。

标签: java json jackson


【解决方案1】:

您可以使用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);
}

但是,由于vicinity 保留在内部几何类之外,您仍然需要手动设置该值。 JsonNode 有必要的方法:

final JsonNode vicinityNode = placesNode.findPath("vicinity");
if (vicinityNode.isTextual()) {
    place.vicinity = vicinityNode.textValue();
}

【讨论】:

  • 感谢您的回答,但我使用一个 ObjectMapper 来映射所有类类型:result = (T) objectMapper.readValue(resultString, aClass);所以我需要在它自己的映射类中解决我的问题,在这种情况下:NearbyPlace
【解决方案2】:

由于您最终会得到NearbyPlaces 的集合,因此您最好手动遍历JsonNode。否则,您正在谈论覆盖集合的反序列化,或者编写可能会变得讨厌的反序列化程序。

下面的例子是递归的。 Java 中的递归是bad(目前),但写起来很有趣。在生产应用程序中,我建议使用循环。

@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();
}

这将返回一个包含 3 个NearbyPlaces 的列表。

【讨论】:

    【解决方案3】:

    我能想到的最简单的解决方案是在 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");
        }
    }
    

    您可能需要对 null 添加一些检查,以防传入的 JSON 缺少某些嵌套对象,即 geometrylocation

    详情请咨询Jackson annotations documentation

    【讨论】:

    • 感谢您的回答,看起来很有帮助,但我今天无法测试。我明天会尝试测试它并提供反馈。
    • 我检查了,现在我有纬度和经度有值,但所有其他使用注释的字段都是空的,你知道吗?
    • 好吧。 ..还没有测试。也许您必须从​​构造函数中的委托映射中提取它们并将每个值分配给其对应的属性。
    猜你喜欢
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2018-08-25
    • 2019-07-27
    • 2014-08-22
    • 2019-11-25
    • 1970-01-01
    相关资源
    最近更新 更多