Google Places detail "photos[]" jsonarray is always null - java

So I get place_id by storing it in a Hashmap with the "name" of the place as the key.
private HashMap<String, String> placeTitleId = new HashMap<>();
if (!place.isNull("place_id")) {
placeId = place.getString("place_id");
placeTitleId.put(name, placeId);
}
Later, I create the Places Detail search url:
private String createPlaceDetailsUrl(String placeId) {
StringBuilder stringBuilder = new StringBuilder("https://maps.googleapis.com/maps/api/place/details/json?");
stringBuilder.append("placeid=").append(placeId);
stringBuilder.append("&key=").append(GOOGLE_PLACES_API_KEY);
return stringBuilder.toString();
}
Finally, I parse the json response:
JSONObject data = new JSONObject(result);
if (data.getString("status").equalsIgnoreCase("OK")) {
JSONArray photoArray = data.getJSONArray("photos");
}
What I don't understand is why the "photos" json array has no value
Android Monitor: W/System.err: org.json.JSONException: No value for photos
The documentation says that the photos[] jsonarray should have up to 10 photos. However, the json output schema does not contain a photos[] object, which I find weird. Is there a problem with how I am obtaining place_id or parsing the response?
EDIT:
The "result" String is incredibly long, but I can provide a gist:
result {
"address components" : [
*bunch of stuff*
]
...
"geometry" : {
*bunch of stuff*
}
"icon"
"id"
"photos" : [
{
"height"
"html_attributions:
"photo_reference!!
}
{
...
"photo_reference!!
}
*bunch more of these*
]
}
EDIT:
Fix is getting json object "result
JSONObject jsonObject = new JSONObject(result);
JSONObject data = new JSONObject("result");
The data object has "pictures"

Try this.
JSONObject data = new JSONObject(result);
// add log here ,make sure you have photos in your result
Log.e("result", result + "");
if (data.getString("status").equalsIgnoreCase("OK")) {
// edited here
JSONArray photoArray = data.optJSONArray("photos");
}
Edit
if (data .has("photos")) {
Log.e("photos", "photos exists");
} else {
Log.e("photos", "photos not exists");
}
Use data .has("photos") in your code and judge it .
Note
Use
JSONObject data = new JSONObject(result);
if(data.has("TAG")){
// if has it in your data,do something
}
to determine whether this tag is present in the data

Related

De-serializing nested JSON to Java in Android Studio

I'm trying to deserialize this JSON to an array of Java objects of class Mural and show them in a list (Recycler View) in my app. Here's formatted example of the JSON with only the data that I need.
{
"records": [{
"recordid": "e6b10b2f7cadbe7caec9a0b36e9e7b570c3add50",
"fields": {
"auteur_s": "Dupa",
"photo": {
"id": "7cd8a2bc799826835057eaec21a28730",
},
"annee": "1994",
"coordonnees_geographiques": [50.8527886675,
4.34530735016],
"personnage_s": "Cubitus - Dommel"
},
},
...
]
}
I use Okhttp to make the request and the response is successful, so I use it to construct a JSONObject.
I traverse the "records" array in that object, because that's where I find all the data I need. Keys that have a string or an array as value work fine and I can load them into my app's Recycler View, but when I want to access "photo", i.e. a key:value pair nested within another object, I get a JSONException org.json.JSONException: No value for photo and my Recycler View returns empty.
Here's what the code looks like:
private void fetchMurals(){
threadExecutor.execute(new Runnable() {
#Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://bruxellesdata.opendatasoft.com/api/records/1.0/search/?dataset=comic-book-route&rows=58")
.get()
.build();
try{
Response response = client.newCall(request).execute();
String json = response.body().string();
JSONObject jsonObject = new JSONObject(json);
JSONArray jsonRecordsArray = jsonObject.getJSONArray("records");
int arraySize = jsonRecordsArray.length();
muralArrayList = new ArrayList<>();
for (int i = 0; i < arraySize; i++){
String jsonID = jsonRecordsArray.getJSONObject(i).getString("recordid");
JSONObject jsonMural = jsonRecordsArray.getJSONObject(i).getJSONObject("fields");
JSONObject jsonMuralPhoto = jsonMural.getJSONObject("photo");
final Mural currentMural = new Mural(
jsonID,
(jsonMural.has("auteur_s")) ? jsonMural.getString("auteur_s") : "Unknown Author",
(jsonMuralPhoto.has("id")) ? jsonMuralPhoto.getString("id") : "No picture available!",
(jsonMural.has("personnage_s")) ? jsonMural.getString("personnage_s") : "Unknown character",
(jsonMural.has("annee")) ? jsonMural.getString("annee") : "Unknown year of creation",
new LatLng(jsonMural.getJSONArray("coordonnees_geographiques").getDouble(0),
jsonMural.getJSONArray("coordonnees_geographiques").getDouble(1))
);
muralArrayList.add(currentMural);
} catch (IOException e){
e.printStackTrace();
}
});
}
I've tried many variations of this but none have worked so far. Could it be a problem with my loop? Or with the jsonMural.getJSONObject("photo") that I am calling?
I see now that I was checking if my record had the field "id" whereas I should have been checking if it had "photo". I changed the line in my constructor to
(jsonArtwork.has("photo")) ? jsonArtwork.getJSONObject("photo").getString("id") : "No picture available!"
Works now.

Null pointer observed while trying to fetch the object value from JSON array

I'm trying to loop the calls: JSON array and trying to fetch the machine details JSON object which is present under calls JSON array list as like below:
{
"<dynamicValue>":{
"type":"CORR-ID",
"tags":[
{
"name":"9VB6454145983212H",
"flags":[
"FLAG_DYNAMIC_VALUE",
"FLAG_ID_LOOKUP_SUPPORTED"
]
}
],
"callSummary":[
{
"colo":"lvs",
"pool":"amazon_paymentsplatformserv",
"machine":"stage2utb29958"
},
{
"colo":"lvs",
"pool":"amazon_elmoserv",
"machine":"msmamoserv_0"
},
{
"colo":"lvs",
"pool":"amazon_xopaymentgatewayserv",
"machine":"msmastmentgatewayserv_1"
},
{
"colo":"lvs",
"pool":"amazon_paymentapiplatserv",
"machine":"msmaentapiplatserv_2"
},
{
"colo":"lvs",
"pool":"amazon_userlifecycleserv_ca",
"machine":"stage2utb91581"
},
{
"colo":"lvs",
"pool":"amazon_dafproxyserv",
"machine":"msmasfproxyserv_1"
},
{
"colo":"lvs",
"pool":"paymentserv",
"machine":"te-alm-15757_paymentexecutionserv_0",
"calls":[
{
"colo":"lvs",
"pool":"fimanagementserv_ca",
"machine":"msmgementserv_ca_20"
},
{
"colo":"lvs",
"pool":"fimanagementserv_ca",
"machine":"msmasgementserv_ca_4"
}
]
}
]
}
}
The above JSON file which I stored in String variable and trying to fetch the machine details which is under calls: JSON ARRAY by using below code.
Code:
public static void getHttpUrlformachineList(String response, String CalId, String componentName)
throws Exception
{
//System.out.println(response);
Map<String, String> data = new HashMap<String, String>();
JSONParser parser = new JSONParser();
JSONObject object = (JSONObject) parser.parse(response);
JSONObject getValue = (JSONObject) object.get(CalId.trim()); //CalId is the dynamic value that mentioned in the JSON input file
JSONObject getCalSummary = (JSONObject) object.get("callSummary");
JSONArray arrays=(JSONArray) getCalSummary.get("calls");
System.out.println(arrays.size()); // return null pointer
}
Error:
java.lang.NullPointerException: null
at com.online.amazon.hadoop.cal.swagger.utils.Utils.getHttpUrlformachineList(Utils.java:112) ~[classes/:na]
If you notice that calls Array List will not be available in all the callSummary JSON Array, and It will be dynamic and can be available under any component that listed above.
So I just want to dynamically get the calls: JSON array and iterate and fetch machine details.
Can someone help me to achieve this?
Note: I'm using JSON-Simple library to parse and iterate the JSON. It would be great if I get solution on the same.
Updated:
I also tried to create callSummary as JSON array and loop that array to get each JSON object and tried to find the calls but this is also leads to Null pointer.
Also the calls json array is not index specific. It can be anywhere in the payload. It may or may not be there in the payload. I just need to handle if it's exist in any of the component then I need to fetch that machine details
change
JSONArray arrays=(JSONArray) getCalSummary.get("calls");
to
JSONArray arrays= getCalSummary.getJSONArray("calls")
and all other functions where you get objects instead of "get" you should use "getJSONObject", "getString" etc.. then you dont have to cast,
also im pretty sure its not arrays.size() its arrays.length() if you are using package org.json.JSONArray but since key "calls" doesnt exist in every "callSummary" you should check if its null or not before.
You should match the types as specified in your JSON string:
public static void getHttpUrlformachineList(String response, String CalId, String componentName)
throws Exception
{
//System.out.println(response);
Map<String, String> data = new HashMap<String, String>();
JSONParser parser = new JSONParser();
JSONObject object = (JSONObject) parser.parse(response);
JSONObject getValue = (JSONObject) object.get(CalId.trim()); //CalId is the dynamic value that mentioned in the JSON input file
JSONArray getCalSummary = (JSONArray) object.get("callSummary"); // callSummary is a JSONArray, not JSONObject
for (int i = 0; i < getCalSummary.length(); i++) {
JSONObject obj = getCalSummary.getJSONObject(i);
if (obj.has("calls")) {
// grab calls array:
JSONArray callsArray = obj.getJSONArray("calls");
}
}
}
Here, you should also check your JSON values with .has(...) method to avoid getting JSONException if a field doesn't exists in your JSONObject.

Fetch JSONObject value from a JSON data object

I have following json data
{
"TestMetrics": {
"ProcessPID": "7887",
"MemSwapped": "0",
"Uptime": "407",
"webTiming": "{\"domainLookupStart\":3,\"domainLookupEnd\":67}"}
}
From this i need to fetch the webTiming json object.
For that i used following code
JSONObject launchMetricsObj = new JSONObject(jsonData);
try {
JSONObject objc = launchMetricsObj.getJSONObject("TestMetrics");
JSONObject webtimingObj = objc.getJSONObject("webTiming");
System.out.println(webtimingObj:::::: " +webtimingObj);
} catch (JSONException e) {
System.out.println("Exception:" + e);
}
As the "webTiming" value is a JSONObject i tried to get it as
JSONObject webtimingObj = objc.getJSONObject("webTiming");
But I observed following Exception:
JSON Objectorg.codehaus.jettison.json.JSONException: JSONObject["webTiming"] is not a JSONObject.
It's because webTiming is defined as a string, not JSONObject.
In order to convert it, you need to do:
JSONObject webtimingObj = new JSONObject(objc.getString("webTiming"));

Parsing JSON fails with not a JSONArray

I am trying to parse the following JSON in Java program.
JSON
{
"data": {
"pageIDentifier":" nametitle",
"page": {
"pageID”:” sports_league_member",
"platform":" www",
"activityType":" ent",
"businessUnit":" ent",
"productLOB":" ent",
"productOffered":" abc",
"productQualifier”:” abc:a bc”,
"flowType”:” sports_com”,
"pageDesc”:” desc”,
"attributes": {
"pageType":" www",
"host”:” finaluser”,
"appId”:” SportsAppID_user”,
"daEnvironment”:” releaser”,
"jvm":" ent_logon_01",
"xCKey":" SportsAppID_user",
"daUID":" jddc9yu5pi1yy6",
"sysEnv”:” user”,
"uri”:” /www/sportscenter”,
"daPageName":" "
}
}
}
}
JAVA Program
URL url = getClass().getResource("test.json");
File file = new File(url.getPath());
String jsonData = readFile(file.getAbsolutePath());
JSONObject jobj = new JSONObject(jsonData);
JSONArray jarr = new JSONArray(jobj.getJSONArray("data").toString());
System.out.println("jarr: " + jarr);
I am getting the following error when executing this code. Please note, jsonData is giving the entire json string without any issue.
org.json.JSONException: JSONObject["data"] is not a JSONArray.
How can i parse "data" value from the above json value? Please advise.
data is not an array
Try this :
System.out.println("jarr: " + jobj.getJSONObject("data").toString());

Java extract from nested JSON

I want to use financial data from yahoo in my program, it already works. I get the complete JSON content and I can display it. But now I want to extract the price as int.
public class Main {
public static void main (String[]args) throws IOException {
String sURL = "http://finance.yahoo.com/webservice/v1/symbols/googl/quote?format=json"; //just a string
// Connect to the URL using java's native library
URL url = new URL(sURL);
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //may be an array, may be an object.
System.out.print(rootobj);
}
}
EDIT
This is the JSON data from yahoo
{
"list" : {
"meta" : {
"type" : "resource-list",
"start" : 0,
"count" : 1
},
"resources" : [
{
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "Google Inc.",
"price" : "554.520020",
"symbol" : "GOOGL",
"ts" : "1432324800",
"type" : "equity",
"utctime" : "2015-05-22T20:00:00+0000",
"volume" : "1213288"
}
}
}
]
}
}
EDIT 2
I changed my code
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject obj = root.getAsJsonObject();
JsonObject result = obj.get("list").getAsJsonObject();
String result2 = result.get("resources").toString();
System.out.print(result2);
And now I already get this
[{"resource":{"classname":"Quote","fields":{"name":"Google Inc.","price":"554.520020","symbol":"GOOGL","ts":"1432324800","type":"equity","utctime":"2015-05-22T20:00:00+0000","volume":"1213288"}}}]
How can I get the "price" now?
EDIT 3
Ok I got it now, it works and I only get the price as double, but is this a smart way to solve this task?
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject obj = root.getAsJsonObject();
JsonObject result = obj.get("list").getAsJsonObject();
JsonArray result2 = result.get("resources").getAsJsonArray();
JsonObject result3 = result2.get(0).getAsJsonObject();
JsonObject result4 = result3.get("resource").getAsJsonObject();
JsonObject result5 = result4.get("fields").getAsJsonObject();
String result6 = result5.get("price").toString();
result6 = result6.replace("\"", "");
double value = Double.parseDouble(result6);
System.out.print(value);
you should reach "fields" object to extract "name", "price" etc.
The org.json library is easy to use. Example code below: your response as a string :
JSONObject obj1 = new JSONObject(response);
JSONArray arr = obj1.getJSONObject("list").getJSONArray("resources"); //GETS RESOURCES ARRAY
for (int i = 0; i < arr.length(); i++)
{
String resource = arr.getJSONObject(i).toString();
JSONObject obj2 = new JSONObject(resource);
String resourceObject = obj2.getJSONObject("resource").toString(); //RESOURCE OBJECT
JSONObject obj3 = new JSONObject(resourceObject);
String name = obj3.getJSONObject("fields").getString("name"); //REACHED THE FIELDS
float price = (float)obj3.getJSONObject("fields").getDouble("price");
System.out.println(name);
System.out.println(price);
}
Download : http://mvnrepository.com/artifact/org.json/json
He is already using gson.
If you want to continue using gson and know the structure before, you could create classes that stores the data.
class GoogleRequest{
private GoogleList list;
public GoogleList getList() {
return list;
}
public void setList(GoogleList list) {
this.list = list;
}
}
// class for list
class GoogleList{
private Meta meta;
private List<Resources> resources;
public List<Resources> getResources() {
return resources;
}
public void setResources(List<Resources> resources) {
this.resources = resources;
}
public Meta getMeta() {
return meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
}
// create other classes here like the Resources class
JsonParser jp = new JsonParser(); // from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream)request.getContent()));
GoogleRequest list = new Gson().fromJson(root,GoogleRequest.class);
The GoogleRequest should hold a List object and a Meta object. gson will introspect and set the properties. gson will set properties to null if they where not introspected. So you could use.
if( list.getResources() != null ){
// list is here
}else{
// do some other code and parse diffrent json
}
If you don't know if it is a array or object create different classes to handle it for you. Just parse the data with new Gson().fromJson();
Now remember that you need right properties for the job. Let's say you have this json in java
String json = "{\"price\" : \"554.520020\"}";
Then price needs to be Double or double. If you use Double you could check
if( obj.getPrice() != null ){
System.out.println( obj.getPrice().intValue() );
}
Note: you will loose precision if you cast double to int

Categories

Resources