【问题标题】:How to parse nested JSON from Map<String, Object>如何从 Map<String, Object> 解析嵌套的 JSON
【发布时间】:2016-11-11 06:33:08
【问题描述】:

我正在使用以下将 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-&gt;geometry-&gt;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"
}

任何帮助将不胜感激。

【问题讨论】:

  • 请分享您的 json 输出和您尝试过的代码
  • @PavneetSingh 我添加了响应 JSON。代码来来去去,所以我可以添加我尝试过的内容。我真的对最好的方法感兴趣吗?
  • 检查这个答案。这就是你要找的东西。 stackoverflow.com/questions/40407198/…
  • 您应该将从apiResponse.get(results) 获得的对象转换为JSONObject。这样,您将访问其中的所有元素..
  • @ViChU 如何从 JSONObject 获取嵌套值?我试过了,但没有运气?

标签: java json spring resttemplate


【解决方案1】:
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) {

获取与键关联的可选双精度值,如果 没有这样的键,或者它的值不是数字。如果值为 字符串,将尝试将其评估为数字。

【讨论】:

  • 您使用的是哪个 JSONObject?我的不支持 getJSONArray
  • @Yonkee 我正在使用org.json.JSONObject
  • 繁荣,它的工作。我认为我在调查期间使用了错误的 JSON 库。感谢您的帮助。
  • @Yonkee 我很高兴它对你有用 :) 快乐编码
【解决方案2】:

理想情况下,您希望使用与在 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;
    }
}

【讨论】:

  • 我已经实现了这个,但仍然不确定如何获取嵌套值? JSONHelper jsonHelper = new JSONHelper(apiResponse.toString());
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    我使用了 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

    【讨论】:

      猜你喜欢
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      • 2020-06-02
      相关资源
      最近更新 更多