3

I am using the below to map a json response to a 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);

I can use the below to output the entire JSON to a string

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

However, what I want to get is a nested value which is results->geometry->location

I have tried a number of solution with JSONArrays, JSONObjects, Substring but can't get them to work.

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

Any help would be greatly appreciated.

6
  • please share your json output and the code what u have tried Commented Nov 11, 2016 at 6:36
  • @PavneetSingh I have added the response JSON. The code has come and gone, so I can add what I have tried. Im really interested in the best approach if you have one? Commented Nov 11, 2016 at 6:40
  • check this answer. It is what you are looking for. stackoverflow.com/questions/40407198/… Commented Nov 11, 2016 at 6:43
  • You should convert the object which you get from apiResponse.get(results) to an JSONObject. In that way , you will access to all the elements inside it.. Commented Nov 11, 2016 at 6:54
  • @ViChU How do I get nested values from a JSONObject? I tried but no luck? Commented Nov 11, 2016 at 7:02

4 Answers 4

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

About optDouble

public double optDouble(String key, double defaultValue) {

Get an optional double associated with a key, or the defaultValue if there is no such key or if its value is not a number. If the value is a string, an attempt will be made to evaluate it as a number.

Sign up to request clarification or add additional context in comments.

4 Comments

Which JSONObject are you using? Mine doesn't support getJSONArray
@Yonkee i am using org.json.JSONObject
Boom, its working. I think I was using the wrong JSON library during my investigation. Thanks for your help.
@Yonkee i am glad that it worked for you :) happy coding
1

Ideally, you would like to access the properties with the same native notation like you would do in JS. Something like this:

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

The following JsonHelper class code (taken from jello-framework) lets you do exactly that.

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

1 Comment

I have implemented this, but still unsure how to get nested values? JSONHelper jsonHelper = new JSONHelper(apiResponse.toString());
0

Use jackson api for parsing,it will be easy

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

Comments

0

I used Gson api and was able to get the location. Try this :

Code::

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

Console Output::

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

So ideally just get the response as a JsonObject instead of a Map and you will be able to read the location.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.