如何从Map <string,object =“”>解析嵌套的JSON

时间:2016-11-11 06:33:09

标签: java json spring resttemplate

我使用以下内容将json响应映射到Map

 Map<String, Object> apiResponse = restTemplate.postForObject("https://maps.googleapis.com/maps/api/geocode/json?address="+defaultLocation+"&key="+API_KEY, httpEntity, Map.class, Collections.EMPTY_MAP);

我可以使用以下内容将整个JSON输出到字符串

    String jsonResponse = apiResponse.get("results").toString();

但是,我想得到的是嵌套值results->geometry->location

我已经尝试了JSONArrays, JSONObjects, Substring的一些解决方案,但无法让它们发挥作用。

回应JSON:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Auckland",
               "short_name" : "Auckland",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Auckland",
               "short_name" : "Auckland",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Auckland",
               "short_name" : "Auckland",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "New Zealand",
               "short_name" : "NZ",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Auckland, New Zealand",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : -36.660571,
                  "lng" : 175.287137
               },
               "southwest" : {
                  "lat" : -37.065475,
                  "lng" : 174.4438016
               }
            },
            "location" : {
               "lat" : -36.8484597,
               "lng" : 174.7633315
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : -36.660571,
                  "lng" : 175.287137
               },
               "southwest" : {
                  "lat" : -37.065475,
                  "lng" : 174.4438016
               }
            }
         },
         "place_id" : "ChIJ--acWvtHDW0RF5miQ2HvAAU",
         "types" : [ "locality", "political" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "Auckland",
               "short_name" : "Auckland",
               "types" : [ "political", "sublocality", "sublocality_level_1" ]
            },
            {
               "long_name" : "Auckland",
               "short_name" : "Auckland",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Auckland",
               "short_name" : "Auckland",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Auckland",
               "short_name" : "Auckland",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "New Zealand",
               "short_name" : "NZ",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "1010",
               "short_name" : "1010",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "Auckland, 1010, New Zealand",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : -36.8364659,
                  "lng" : 174.7838398
               },
               "southwest" : {
                  "lat" : -36.8621041,
                  "lng" : 174.7503805
               }
            },
            "location" : {
               "lat" : -36.8484597,
               "lng" : 174.7633315
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : -36.8364659,
                  "lng" : 174.7838398
               },
               "southwest" : {
                  "lat" : -36.8621041,
                  "lng" : 174.7503805
               }
            }
         },
         "place_id" : "ChIJuZqpSPtHDW0R4LOiQ2HvAAU",
         "types" : [ "political", "sublocality", "sublocality_level_1" ]
      }
   ],
   "status" : "OK"
}

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:3)

JSONObject obj=new JSONObject(jsonresult);
// get result array
JSONArray resultsarray= obj.getJSONArray("results"); 
for (int i=0;i<resultsarray.length(),i++){
        // get Objects using index
        JSONObject jsonobject= results.getJSONObject(i);
        // get geometry object
        JSONObject geometry= jsonobject.getJSONObject("geometry");
        // get location object from geometry
        JSONObject location= geometry.getJSONObject("location");

        // get location values from location object
        double lat = location.optDouble("lat",0.0);
        double long = location.optDouble("lng",0.0);
 }

关于optDouble

public double optDouble(String key, double defaultValue) {
  

获取与键关联的可选double,或者defaultValue if   没有这样的密钥,或者它的值不是数字。如果值是   一个字符串,将尝试将其评估为数字。

答案 1 :(得分:0)

理想情况下,您希望使用与JS中相同的本机表示法访问属性。像这样:

String url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + address;
String responseStr = fetch(url);
JsonHelper response =  JsonHelper.forString(responseStr);

String status = (String) response.getValue("status");
if(status != null && status.equals("OK")) {
   lat = (Double) response.getValue("results[0].geometry.location.lat");        
   lng = (Double) response.getValue("results[0].geometry.location.lng");
}

以下JsonHelper类代码(取自jello-framework)可让您完全执行此操作。

package jello.common;

import java.util.List;

import com.google.gson.Gson;
import java.util.AbstractMap;

public class JsonHelper {

    private Object json;

    public JsonHelper(String jsonString) {
        Gson g = new Gson();
        json = g.fromJson(jsonString, Object.class);
    }

    public static JsonHelper forString(String jsonString) {
        return new JsonHelper(jsonString);
    }

    @SuppressWarnings("unchecked")
    public Object getValue(String path) {
        Object value = json;
        String [] elements = path.split("\\.");
        for(String element : elements) {
            String ename = element.split("\\[")[0];

            if(AbstractMap.class.isAssignableFrom(value.getClass())) {
                value = ( (AbstractMap<String, Object>) value).get(ename);

                if(element.contains("[")) {
                    if(List.class.isAssignableFrom(value.getClass())) {
                        Integer index = Integer.valueOf(element.substring(element.indexOf("[")+1, element.indexOf("]")) );
                        value = ((List<Object>) value).get(index);
                    }
                    else {
                        return null;
                    }
                }
            }
            else {
                return null;
            }
        }

        return value;
    }
}

答案 2 :(得分:0)

使用jackson api进行解析,这很容易

        ObjectMapper mapper = new ObjectMapper();
        JsonNode node = mapper.readTree(json);
        if(node.get("results").isArray()){
            for(int i=0; i <= node.get("results").size()-1; i++){
                System.out.println(node.get("results").get(i));
            }

答案 3 :(得分:0)

我使用了Gson api并且能够获得该位置。试试这个:

<强>代码::

    Gson gson = new Gson();

    String json = "your json";

    JsonObject map = gson.fromJson(json, JsonObject.class); // to be replaced with your restTemplate call
    JsonArray arr = map.getAsJsonArray("results");

    for (Object j : arr) {
        System.out.println(((JsonObject) j).get("geometry").getAsJsonObject().get("location"));
    }

控制台输出::

{"lat":-36.8484597,"lng":174.7633315}
{"lat":-36.8484597,"lng":174.7633315}

理想情况下,只需将回复设为JsonObject而不是Map,您就可以阅读location