簡體   English   中英

傑克遜解析樹的反應

[英]Jackson parse tree response

我想解析谷歌附近的地方響應,一個項目有這種格式:

         "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”而不為每個節點創建另一個類?

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

由於您最終會得到一個NearbyPlace集合, NearbyPlace您最好只需手動遍歷JsonNode 否則你談論的是對集合的重新反序列化,或者編寫一個可能令人討厭的反序列化器。

下面的示例是遞歸的。 Java中的遞歸很糟糕 (現在),但編寫很有趣。 在生產應用程序中,我建議循環。

@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個NearbyPlace的列表。

我能想到的最簡單的解決方案是在您的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");
    }
}

如果傳入的JSON缺少某些嵌套對象(即geometrylocation ,您可能希望對null添加一些檢查。

有關更多詳細信息,請參閱Jackson注釋文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM