How to parse nested JSON from Map<String, Object> - java

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.

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.

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

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

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.

Related

java.lang.StringIndexOutOfBoundsException: length=10684; index=10684

In my Android Project, I'm trying to use PolyUtil.decode to draw a polyline on google map using a response from google maps API.
Here is the code I've used for this :
public void gettingDerictions(double sourceLat, double sourceLong, double destLat, double destLong) {
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + sourceLat + "," + sourceLong + "&destination=" + destLat + "," + destLong + "&key=****************************";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
Log.e("The response", response);
List<LatLng> route = PolyUtil.decode(response);
System.out.println(route);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("The response", "it didn't work");
}
});
queue.add(stringRequest);
}
I'm getting this error:
07-31 22:04:13.486 21530-21530/com.innoventiq.arkbeh E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.innoventiq.arkbeh, PID: 21530
java.lang.StringIndexOutOfBoundsException: length=10684; index=10684
at java.lang.String.charAt(Native Method)
at com.google.maps.android.PolyUtil.decode(PolyUtil.java:464)
at com.innoventiq.arkbeh.MapsActivity$6.onResponse(MapsActivity.java:260)
at com.innoventiq.arkbeh.MapsActivity$6.onResponse(MapsActivity.java:255)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7406)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
UPDATE
Here is the value of response.
{
"geocoded_waypoints" : [
{
"geocoder_status" : "OK",
"place_id" : "Ek82IFJpY2ggSG9tZSwgQWwgQWdhbXkgQWwgQmFocmksIFFlc20gQWQgRGVraGlsYWgsIEFsZXhhbmRyaWEgR292ZXJub3JhdGUsIEVneXB0IhoSGAoUChIJv3T_1uiU9RQR7X1tYzsaZ8QQBg",
"types" : [ "street_address" ]
},
{
"geocoder_status" : "OK",
"place_id" : "ChIJ83j9iddBWBQR3SDSTdvOCbk",
"types" : [ "airport", "establishment", "point_of_interest" ]
}
],
"routes" : [
{
"bounds" : {
"northeast" : {
"lat" : 31.1095921,
"lng" : 31.2352784
},
"southwest" : {
"lat" : 30.0439783,
"lng" : 29.7347456
}
},
"copyrights" : "Map data ©2019 ORION-ME",
"legs" : [
{
"distance" : {
"text" : "206 km",
"value" : 206160
},
"duration" : {
"text" : "2 hours 29 mins",
"value" : 8967
},
"end_address" : "Nasser, Madinaty, محافظة القاهرة‬ 11566, Egypt",
"end_location" : {
"lat" : 30.0445393,
"lng" : 31.2352658
},
"start_address" : "6 Rich Home, Al Agamy Al Bahri, Qesm Ad Dekhilah, Alexandria Governorate, Egypt",
"start_location" : {
"lat" : 31.1092252,
"lng" : 29.7598111
},
"steps" : [
{
"distance" : {
"text" : "57 m",
"value" : 57
},
"duration" : {
"text" : "1 min",
"value" : 15
},
"end_location" : {
"lat" : 31.1089022,
"lng" : 29.7602755
},
"html_instructions" : "Head \u003cb\u003esoutheast\u003c/b\u003e toward \u003cb\u003eRich Home\u003c/b\u003e",
"polyline" : {
"points" : "u_{|DymstDLU`#q#PU"
},
"start_location" : {
"lat" : 31.1092252,
"lng" : 29.7598111
},
"travel_mode" : "DRIVING"
},
{
"distance" : {
"text" : "0.1 km",
"value" : 106
},
"duration" : {
"text" : "1 min",
"value" : 41
},
"end_location" : {
"lat" : 31.1095921,
"lng" : 29.7610398
},
"html_instructions" : "Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eRich Home\u003c/b\u003e",
"maneuver" : "turn-left",
"polyline" : {
"points" : "s}z|DwpstDIKu#cAiAgA"
},
"start_location" : {
"lat" : 31.1089022,
"lng" : 29.7602755
},
"travel_mode" : "DRIVING"
},
{
"distance" : {
"text" : "1.6 km",
"value" : 1553
},
"duration" : {
"text" : "8 mins",
"value" : 485
},
"end_location" : {
"lat" : 31.0988067,
"lng" : 29.7712707
},
Your response object is not well formatted before decoding. Try below implementation
public void gettingDerictions(double sourceLat, double sourceLong, double destLat, double destLong) {
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + sourceLat + "," + sourceLong + "&destination=" + destLat + "," + destLong + "&key=****************************";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
// Log.e("The response", response);
// List<LatLng> route = PolyUtil.decode(response);
// System.out.println(route);
List<LatLng> movements = new ArrayList<LatLng>();
try{
JSONObject json = new JSONObject(response);
//Retrieve routes from response
JSONObject jsonRoute = json.getJSONArray("routes").getJSONObject(0);
//Retrieve legs from routes
JSONObject legs = jsonRoute.getJSONArray("legs").getJSONObject(0);
//Retrieve steps from legs
JSONArray steps = legs.getJSONArray("steps");
final int numSteps = steps.length();
JSONObject step;
//Retrieve points from steps
for (int i = 0; i < numSteps; i++) {
step = steps.getJSONObject(i);
String pontos = step.getJSONObject("polyline").getString("points");
movements.addAll(PolyUtil.decode(pontos));
}
}catch(Exception ex){
Log.d("DirectionErr",ex.getMessage());
}
//make use of movements object here
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("The response", "it didn't work");
}
});
queue.add(stringRequest);
}
EDIT:
I just realized there is an easier way to fix this. If you are getting your response in json then you should use JsonObjectRequest instead of String request, it will give you properly encoded Json that you can parse to String.
OLD ANSWER:.
This must have been caused by Escape Characters during encoding/decoding since you are using string.
Just remove unescape characters and it should work:
response = StringEscapeUtils.unescapeJava(polyLine);
There is an implementation of StringEscapeUtils in Apache commons-text, you can use it from here:
https://github.com/apache/commons-text/blob/master/src/main/java/org/apache/commons/text/StringEscapeUtils.java

google-maps-services java library result differs from browser call result

I am using this java libraray
<dependency>
<groupId>com.google.maps</groupId>
<artifactId>google-maps-services</artifactId>
<version>0.1.15</version>
</dependency>
And when I execute the code below
public static GeocodingResult getGeocode(String address) {
GeocodingResult[] results;
try {
GeoApiContext context = new GeoApiContext().setApiKey(GOOGLE_KEY);
results = GeocodingApi.geocode(context, address).await();
if (results.length > 0) {
return results[0];
} else {
return null;
}
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
public static void main(String[] args) {
GeocodingResult geocode = getGeocode("Imanova 19, Astana");
System.out.println(geocode.geometry.location.lat);
}
Result gives
INFO: Request: https://maps.googleapis.com/maps/api/geocode/json?key=MY_GOOGLE_KEY&address=Imanova+19%2C+Astana
51.16052269999999
But, when I try to call the same given request from browser, it gives another result.
The question is, why so and how to fix?
Edit from the comments:
Result of https://maps.googleapis.com/maps/api/geocode/json?address=Imanova+19%2C+Astana
{
"results" : [
{
"address_components" : [
{
"long_name" : "Astaná",
"short_name" : "Astaná",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Astana",
"short_name" : "Astana",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "Kazajistán",
"short_name" : "KZ",
"types" : [ "country", "political" ]
},
{
"long_name" : "020000",
"short_name" : "020000",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "Astaná 020000, Kazajistán",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 51.2903453,
"lng" : 71.7427397
},
"southwest" : {
"lat" : 51.0055461,
"lng" : 70.9179879
}
},
"location" : {
"lat" : 51.16052269999999,
"lng" : 71.47035579999999
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 51.2903453,
"lng" : 71.7427397
},
"southwest" : {
"lat" : 51.0055461,
"lng" : 70.9179879
}
}
},
"partial_match" : true,
"place_id" : "ChIJCUa1fcSARUIRKJKx3Y0U-Zc",
"types" : [ "locality", "political" ]
}
],
"status" : "OK"
}
This answer https://stackoverflow.com/a/30749036/1862262 fully describes the solution for my problem.
In the same way I set region
GeocodingResult[] results = GeocodingApi.geocode(context, address).region("KZ").await();
And got the same result as the result in browser.
But I don't know what region it takes if it's not set.
Here is documentation about this option and problem https://developers.google.com/maps/documentation/geocoding/#RegionCodes

ElasticSearch Querying and OR

Here's my mapping
{
"app" : {
"mappings" : {
"patient" : {
"properties" : {
"LastName" : {
"type" : "string"
},
"consultations" : {
"type" : "nested",
"properties" : {
"deleted" : {
"type" : "boolean"
},
"diagnosis" : {
"type" : "string"
},
"documentDate" : {
"type" : "date",
"format" : "dateOptionalTime"
},
"firstName" : {
"type" : "string"
},
"lastName" : {
"type" : "string"
},
"middleName" : {
"type" : "string"
},
"prescriptions" : {
"type" : "string"
}
}
},
"firstName" : {
"type" : "string"
},
"gender" : {
"type" : "string"
},
"id" : {
"type" : "string",
"index" : "not_analyzed"
},
"lastName" : {
"type" : "string"
},
"middleName" : {
"type" : "string"
},
"owner" : {
"type" : "string",
"index" : "not_analyzed"
},
"patientPin" : {
"type" : "string"
}
}
}
}
}
}
Then let's say I have this data
{
"id":"21",
"firstName":"Scrappy",
"patientPin":"2012010000000021",
"middleName":"D",
"consultations":[
{
"id":null,
"prescriptions":[
"GADOTERIC Acid DOTAREM"
],
"diagnosis":[
"Kawasaki's Disease",
"Alcohol Intoxication"
],
"documentDate":"2014-07-31T13:19:00.000+08:00",
"deleted":false,
"lastName":"Doo",
"firstName":"Scrappy",
"middleName":"D"
}
],
"owner":"TENANT1",
"gender":"FEMALE",
"lastName":"Doo"
}
{
"id":"100066",
"firstName":"Kyel ",
"patientPin":"201408000001",
"middleName":"John ",
"consultations":[
{
"id":null,
"prescriptions":[
],
"diagnosis":[
"headache"
],
"documentDate":"2014-08-05T10:10:00.000+08:00",
"deleted":false,
"lastName":"David",
"firstName":"Mika",
"middleName":"John "
}
],
"owner":"TENANT1",
"gender":"MALE",
"lastName":"David"
}
How do I query patients that has consultations that has a "headache" OR "Alcohol Intoxication"?
For your result I am suggesting you to use filter.
You can achieve this using,
For or, terms filter match document with any of value provided (which means does or for values)
client.prepareSearch("app").setTypes("patient").setPostFilter(
FilterBuilders.termsFilter("consultations.diagnosis","headache","Alcohol Intoxication")
);
For and,
client.prepareSearch("app").setTypes("patient").setPostFilter(
FilterBuilders.andFilter(
FilterBuilders.termsFilter("consultations.diagnosis","headache"),
FilterBuilders.termsFilter("consultations.diagnosis","Alcohol Intoxication")
)
);
For this, Any value you want to filter should be index : not_analyzed .
try learning elasticsearch.

Retrieving values from nested JSON Object

I've got JSON file, which I want to parse.
The JSON file ("myfile") has format as follows:
{
"LanguageLevels": {
"1": "Początkujący",
"2": "ŚrednioZaawansowany",
"3": "Zaawansowany",
"4": "Ekspert"
}
}
I want to retrieve value (ŚrednioZaawansowany) of Key 2 from Language Levels.
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class JsonSimpleExample {
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("myfile");
JSONObject jsonObject = (JSONObject) obj;
JSONObject jsonChildObject = (JSONObject)jsonObject.get("LanguageLevels");
What to do next? How I can iterate over it?
Maybe you're not using the latest version of a JSON for Java Library.
json-simple has not been updated for a long time, while JSON-Java was updated 2 month ago.
JSON-Java can be found on GitHub, here is the link to its repo: https://github.com/douglascrockford/JSON-java
After switching the library, you can refer to my sample code down below:
public static void main(String[] args) {
String JSON = "{\"LanguageLevels\":{\"1\":\"Pocz\\u0105tkuj\\u0105cy\",\"2\":\"\\u015arednioZaawansowany\",\"3\":\"Zaawansowany\",\"4\":\"Ekspert\"}}\n";
JSONObject jsonObject = new JSONObject(JSON);
JSONObject getSth = jsonObject.getJSONObject("LanguageLevels");
Object level = getSth.get("2");
System.out.println(level);
}
And as JSON-Java open-sourced, you can read the code and its document, they will guide you through.
Hope that it helps.
You will have to iterate step by step into nested JSON.
for e.g a JSON received from Google geocoding api
{
"results" : [
{
"address_components" : [
{
"long_name" : "Bhopal",
"short_name" : "Bhopal",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Bhopal",
"short_name" : "Bhopal",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Madhya Pradesh",
"short_name" : "MP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Bhopal, Madhya Pradesh, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 23.3326697,
"lng" : 77.5748062
},
"southwest" : {
"lat" : 23.0661497,
"lng" : 77.2369767
}
},
"location" : {
"lat" : 23.2599333,
"lng" : 77.412615
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 23.3326697,
"lng" : 77.5748062
},
"southwest" : {
"lat" : 23.0661497,
"lng" : 77.2369767
}
}
},
"place_id" : "ChIJvY_Wj49CfDkR-NRy1RZXFQI",
"types" : [ "locality", "political" ]
}
],
"status" : "OK"
}
I shall iterate in below given fashion
to "location" : {
"lat" : 23.2599333,
"lng" : 77.412615
//recieve JSON in json object
JSONObject json = new JSONObject(output.toString());
JSONArray result = json.getJSONArray("results");
JSONObject result1 = result.getJSONObject(0);
JSONObject geometry = result1.getJSONObject("geometry");
JSONObject locat = geometry.getJSONObject("location");
//"iterate onto level of location";
double lat = locat.getDouble("lat");
double lng = locat.getDouble("lng");
You can see that JSONObject extends a HashMap, so you can simply use it as a HashMap:
JSONObject jsonChildObject = (JSONObject)jsonObject.get("LanguageLevels");
for (Map.Entry in jsonChildOBject.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
JSONArray jsonChildArray = (JSONArray) jsonChildArray.get("LanguageLevels");
JSONObject secObject = (JSONObject) jsonChildArray.get(1);
I think this should work, but i do not have the possibility to test it at the moment..
To see all keys of Jsonobject use this
String JSON = "{\"LanguageLevels\":{\"1\":\"Pocz\\u0105tkuj\\u0105cy\",\"2\":\"\\u015arednioZaawansowany\",\"3\":\"Zaawansowany\",\"4\":\"Ekspert\"}}\n";
JSONObject obj = new JSONObject(JSON);
Iterator iterator = obj.keys();
String key = null;
while (iterator.hasNext()) {
key = (String) iterator.next();
System.out.pritnln(key);
}
Try this, you can parse nested JSON
public static String getJsonValue(String jsonReq, String key) {
JSONObject json = new JSONObject(jsonReq);
boolean exists = json.has(key);
Iterator<?> keys;
String nextKeys;
String val = "";
if (!exists) {
keys = json.keys();
while (keys.hasNext()) {
nextKeys = (String) keys.next();
try {
if (json.get(nextKeys) instanceof JSONObject) {
return getJsonValue(json.getJSONObject(nextKeys).toString(), key);
} else if (json.get(nextKeys) instanceof JSONArray) {
JSONArray jsonArray = json.getJSONArray(nextKeys);
int i = 0;
if (i < jsonArray.length()) do {
String jsonArrayString = jsonArray.get(i).toString();
JSONObject innerJson = new JSONObject(jsonArrayString);
return getJsonValue(innerJson.toString(),key);
} while (i < jsonArray.length());
}
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
val = json.get(key).toString();
}
return val;
}
Here is an example of retrieving nested JSON object.
Department and Product are model classes.
Department class holds department as a String and products as ArrayList of Product
Product class holds name as a String
depts and products are ArrayList of corresponding model classes
String jsonDataString = readJSONDataFromFile();
JSONArray jsonArray = new JSONArray(jsonDataString);
for (int i=0; i<jsonArray.length(); ++i) {
JSONObject departmentJSONObject = jsonArray.getJSONObject(i);
String deptName = departmentJSONObject.getString("department");
JSONArray productsJSONArray = departmentJSONObject.getJSONArray("products");
for (int j =0; j <productsJSONArray.length();j++){
JSONObject productJSONObject = productsJSONArray.getJSONObject(j);
String prodName = productJSONObject.getString("name");
Product product = new Product(prodName);
products.add(product);
}
Department department = new Department(deptName, products);
depts.add(department);
Here is my raw json file
[
{
"department": "Cold Drink",
"products": [
{
"name": "lemonade",
"img": "some_url"
},
{
"name": "Oj",
"img": "some_url"
}
]
},
{
"department": "CD2",
"products": [
{
"name": "lemonade2",
"img": "some_url2"
},
{
"name": "oj2",
"img": "some_url2"
}
]
},
{
"department": "CD3",
"products": [
{
"name": "lemonade3",
"img": "some_url3"
},
{
"name": "oj3",
"img": "some_url3"
}
]
}
]

How to get specific details from reverse Geo-coder response by using Spring

This is my code for getting response from Geo-coder:
public class Snippet {
private GeoCodeResponse getAddressFromLatLng(double lattitute,
double longtitute) throws ClientProtocolException, IOException {
String latitude = String.valueOf(lattitute);
String longitude = String.valueOf(longtitute);
String URL = "http://maps.google.com/maps/api/geocode/json?latlng="
+ latitude + "," + longitude + "&sensor=true";
RestTemplate restTemplate = new RestTemplate();
ObjectMapper mapper = new ObjectMapper();
String forObject = restTemplate.getForObject(URL, String.class);
GeoCodeResponse geoCodeResponse = mapper.readValue(forObject,
GeoCodeResponse.class);
System.out.println(forObject);
return geoCodeResponse;
}
public static void main(String[] args) throws ClientProtocolException,
IOException {
GeoCodeResponse geoCoderResponse = new TrackServiceImpl()
.getAddressFromLatLng(17.42560, 78.548339);
if (geoCoderResponse.getStatus().equals("OK")) {
List<Results> listOfResults = geoCoderResponse.getResults();
for (Results result : listOfResults) {
// get Results Object
Iterator<Results> results = listOfResults.iterator();
while (results.hasNext()) {
result = results.next();
System.out.println(result.getFormatted_address());
// get Address Object
Collection<AddressComponent> addresscomponents = result
.getAddress_components();
Iterator<AddressComponent> addresscomponentsIterator = addresscomponents
.iterator();
while (addresscomponentsIterator.hasNext()) {
AddressComponent addressComponent = addresscomponentsIterator
.next();
System.out.println(addressComponent.getLong_name());
System.out.println(addressComponent.getShort_name());
}
// get Geometry Object
Geometry geometry = result.getGeometry();
System.out.println(geometry.getLocation_type());
// get Location Object
Location location = geometry.getLocation();
System.out.println(location.getLat());
System.out.println(location.getLng());
}
break;
}
}
}
private GeoCodeResponse getAddressFromLatLng(double lattitute,
double longtitute) throws ClientProtocolException, IOException {
String latitude = String.valueOf(lattitute);
String longitude = String.valueOf(longtitute);
String URL = "http://maps.google.com/maps/api/geocode/json?latlng="
+ latitude + "," + longitude + "&sensor=true";
RestTemplate restTemplate = new RestTemplate();
ObjectMapper mapper = new ObjectMapper();
String forObject = restTemplate.getForObject(URL, String.class);
GeoCodeResponse geoCodeResponse = mapper.readValue(forObject,
GeoCodeResponse.class);
System.out.println(forObject);
return geoCodeResponse;
}
}
This is the geo coder response:
{
"results" : [
{
"address_components" : [
{
"long_name" : "4-1-91/3",
"short_name" : "4-1-91/3",
"types" : []
},
{
"long_name" : "Nacharam Mallapur Road",
"short_name" : "Nacharam Mallapur Road",
"types" : [ "route" ]
},
{
"long_name" : "Bhavani Nagar",
"short_name" : "Bhavani Nagar",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Tarnaka",
"short_name" : "Tarnaka",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Secunderabad",
"short_name" : "SC",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Ranga Reddy",
"short_name" : "R.R. District",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
},
{
"long_name" : "500076",
"short_name" : "500076",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "4-1-91/3, Nacharam Mallapur Road, Bhavani Nagar, Tarnaka, Secunderabad, Andhra Pradesh 500076, India",
"geometry" : {
"location" : {
"lat" : 17.4251743,
"lng" : 78.5480111
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 17.4265232802915,
"lng" : 78.54936008029151
},
"southwest" : {
"lat" : 17.4238253197085,
"lng" : 78.54666211970849
}
}
},
"types" : [ "street_address" ]
},
{
"address_components" : [
{
"long_name" : "Bhavani Nagar",
"short_name" : "Bhavani Nagar",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Tarnaka",
"short_name" : "Tarnaka",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Secunderabad",
"short_name" : "SC",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Ranga Reddy",
"short_name" : "R.R. District",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Bhavani Nagar, Tarnaka, Secunderabad, Andhra Pradesh, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 17.4276068,
"lng" : 78.550246
},
"southwest" : {
"lat" : 17.4249009,
"lng" : 78.54588509999999
}
},
"location" : {
"lat" : 17.4261285,
"lng" : 78.5479845
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 17.4276068,
"lng" : 78.550246
},
"southwest" : {
"lat" : 17.4249009,
"lng" : 78.54588509999999
}
}
},
"types" : [ "sublocality", "political" ]
},
{
"address_components" : [
{
"long_name" : "500076",
"short_name" : "500076",
"types" : [ "postal_code" ]
},
{
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Andhra Pradesh 500076, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 17.4503108,
"lng" : 78.59751469999999
},
"southwest" : {
"lat" : 17.4199893,
"lng" : 78.5419289
}
},
"location" : {
"lat" : 17.4381342,
"lng" : 78.56040689999999
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 17.4503108,
"lng" : 78.59751469999999
},
"southwest" : {
"lat" : 17.4199893,
"lng" : 78.5419289
}
}
},
"types" : [ "postal_code" ]
},
{
"address_components" : [
{
"long_name" : "Hyderabad",
"short_name" : "Hyderabad",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Hyderabad, Andhra Pradesh, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 17.4823267,
"lng" : 78.5604858
},
"southwest" : {
"lat" : 17.3486722,
"lng" : 78.4018707
}
},
"location" : {
"lat" : 17.385044,
"lng" : 78.486671
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 17.4823267,
"lng" : 78.5604858
},
"southwest" : {
"lat" : 17.3486722,
"lng" : 78.4018707
}
}
},
"types" : [ "administrative_area_level_2", "political" ]
},
{
"address_components" : [
{
"long_name" : "Secunderabad",
"short_name" : "SC",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Hyderabad",
"short_name" : "Hyderabad",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Secunderabad, Andhra Pradesh, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 17.6393052,
"lng" : 78.64442819999999
},
"southwest" : {
"lat" : 17.4124778,
"lng" : 78.47253499999999
}
},
"location" : {
"lat" : 17.4399295,
"lng" : 78.4982741
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 17.6393052,
"lng" : 78.64442819999999
},
"southwest" : {
"lat" : 17.4124778,
"lng" : 78.47253499999999
}
}
},
"types" : [ "locality", "political" ]
},
{
"address_components" : [
{
"long_name" : "Ranga Reddy",
"short_name" : "R.R. District",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Ranga Reddy, Andhra Pradesh, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 17.701268,
"lng" : 78.8475038
},
"southwest" : {
"lat" : 16.8492337,
"lng" : 77.3753358
}
},
"location" : {
"lat" : 17.2031945,
"lng" : 77.8367282
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 17.701268,
"lng" : 78.8475038
},
"southwest" : {
"lat" : 16.8492337,
"lng" : 77.3753358
}
}
},
"types" : [ "administrative_area_level_2", "political" ]
},
{
"address_components" : [
{
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Andhra Pradesh, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 19.916715,
"lng" : 84.80412939999999
},
"southwest" : {
"lat" : 12.596836,
"lng" : 76.749786
}
},
"location" : {
"lat" : 17.0477624,
"lng" : 80.0981869
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 19.916715,
"lng" : 84.80412939999999
},
"southwest" : {
"lat" : 12.596836,
"lng" : 76.749786
}
}
},
"types" : [ "administrative_area_level_1", "political" ]
},
{
"address_components" : [
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 35.5044752,
"lng" : 97.395555
},
"southwest" : {
"lat" : 6.747138899999999,
"lng" : 68.1623859
}
},
"location" : {
"lat" : 20.593684,
"lng" : 78.96288
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 35.5044752,
"lng" : 97.395555
},
"southwest" : {
"lat" : 6.747138899999999,
"lng" : 68.1627956
}
}
},
"types" : [ "country", "political" ]
}
],
"status" : "OK"
}
Here my question is how to get these from below objects ?
> address components:
"long_name" : "Secunderabad",
"short_name" : "SC",
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
"long_name" : "Andhra Pradesh",
"short_name" : "AP",
> location :
"lat" : 17.4251743,
"lng" : 78.5480111**
Please help me, I unable to get this formatted address.
Thanks in advance.

Categories