How to parse multidimensional json array in java - java

I have a two dimensional JSON array object like below
{"enrollment_response":{"condition":"Good","extra":"Nothig","userid":"526398"}}
I would like to parse the above Json array object to get the condition, extra, userid.So i have used below code
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("D:\\document(2).json"));
JSONObject jsonObject = (JSONObject) obj;
String name = (String) jsonObject.get("enrollment_response");
System.out.println("Condition:" + name);
String name1 = (String) jsonObject.get("extra");
System.out.println("extra: " + name1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
Its throwing an error as
"Exception in thread "main" java.lang.ClassCastException:
org.json.simple.JSONObject cannot be cast to java.lang.String at
com.jsonparser.apps.JsonParsing1.main(JsonParsing1.java:22)"
Please anyone help on this issue.

First of all: Do not use the JSON parsing library you're using. It's horrible. No, really, horrible. It's an old, crufty thing that lightly wraps a Java rawtype Hashmap. It can't even handle a JSON array as the root structure.
Use Jackson, Gson, or even the old json.org library.
That said, to fix your current code:
JSONObject enrollmentResponseObject =
(JSONObject) jsonObject.get("enrollment_response");
This gets the inner object. Now you can extract the inner fields:
String condition = (String) enrollmentResponseObject.get("condition");
And so forth. The whole library simply extends a Hashmap (without using generics) and makes you figure out and cast to the appropriate types.

Below line,
String name = (String) jsonObject.get("enrollment_response");
should be
String name = jsonObject.getJSONObject("enrollment_response").getString("condition");
Value of enrollment_response is again a Json.

This works, but trust me: change library.
JSONObject jsonObject = (JSONObject) obj;
JSONObject name = (JSONObject) jsonObject.get("enrollment_response");
System.out.println("Condition:" + name);
String name1 = (String) name.get("extra");
System.out.println("extra: " + name1);

Related

How to convert string into JSONObject?

I have a string with value abc#xyz.com.
I have to pass this value to server like:
{"email":"abc#xyz.com"}
I am passing value to server like this using okhttp:
Map<String, String> map = new HashMap<>();
map.put("email", email);
new PostMethodWithProgress(login_url, map, this, new Callback()
{
#Override
public void done(String reply)
{
try
{
JSONObject object = new JSONObject(reply);
if (object.getString("status").equals("200"))
{
//Toast Success Message
}
else
{
//Toast Failure Message
}
}
catch (Exception e)
{
Log.e("ASA", "Error is: " + e);
}
}
}).execute();
How do i do it?
You can simply use JSONObject to achieve this
JSONObject jsonObject = new JSONObject();
jsonObject.put("email", "abc#xyz.com");
String result = jsonObject.toString();
Output:
{"email":"abc#xyz.com"}
Use Google Gson convert string to model and model to string easily
ConvertModel convertModel = new Gson().fromJson(reply, ConvertModel .class);
Then you can validate easily
easy way use this code to pass jsonobject as string in okhttp
String jsonString = "";
try {
JSONObject obj = new JSONObject();
obj.put("email", "abc#xyz.com");
obj.put("pwd", "12356");
jsonString = obj.toString();
//out put like this -> {"email":"abc#xyz.com","pwd":"123456"}
Log.d("JsonString__",jsonString);
}catch (Exception e){};
JsonObject is a modifiable set of name/value mappings. Names are unique, non-null strings. Values may be any mix of JSONObject, JSONArray, Strings, Booleans, Integers, Longs, Doubles or NULL.
for your case key is email and value is abc#xyz.com so as I told JsonObject we can put both key and value pair like below -
JsonObject object = new JsonObject();
object.put("email","abc#xyz.com");
If we convert above JsonObject to string then its value would be -
{"email":"abc#xyz.com"}
hope this will help you.
try out this code with your data.
/**
* This method is used to create text size and color code json and store it in json object.
*
* #param textSize text size entered into edit text.
* #param colorOfPreview text color of custom text color.
* #return return json object of created text size and color.
*/
private String createJSONObject(String textSize, int colorOfPreview) {
JSONObject jsonObject = new JSONObject();
try {
// put your values here
jsonObject.put("textSize", textSize);
jsonObject.put("textColor", colorOfPreview);
return jsonObject.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return jsonObject.toString();
}

How to fix 'JsonNull cannot be cast to JsonObject'

I call a post API which responds with details on specific addresses, however some of the responses that get returned have no data so they'll be returned as null. How do I stop the casting error in my code?
I currently only get the data as a Json Object and I'm not sure how to rework my code that so when a JsonNull Element gets returned I can handle that data.
JsonElement element = new JsonParser().parse(jsonString);
JsonObject jsonObject = element.getAsJsonObject();
jsonObject = jsonObject.getAsJsonObject("response"); // This is either an object or it is null
String buildName = jsonObject.get("buildingName").getAsString();
String buildNum = jsonObject.get("premisesNumber").getAsString();
String streetName = jsonObject.get("streetName").getAsString();
What I expect to be returned would be either the address details for valid addresses or no information at all for the invalid addresses.
The error that gets produced is this:
java.lang.ClassCastException: com.google.gson.JsonNull cannot be cast to com.google.gson.JsonObject
Before getAsString() check for isJsonNull(). It'll return true if object is Null.
You can rewrite your code as below
String buildName= (jsonObject.get("buildingName").isJsonNull ? null : jsonObject.get("buildingName").getAsString());
Normally is a good idea validate the data is JSON valid
public static boolean isJSONValid(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
try {
new JSONArray(test);
} catch (JSONException ex1) {
return false;
}
}
return true;
}
Function above will return you true in case the string is a valid JSON object(could be an object or an array of objects).
After that you can continue parsing using Jackson lib or the GSON lib

Java get nested JSON object/array

Code used:
jObj = new JSONObject(json);
newJSONString = jObj.getString("payload");
JArray = new JSONArray(newJSONString);
This is what JArray looks like:
[{"06:30:00":{"color":"grey","time_color":"black"},"06:45:00":{"color":"grey","time_color":"black"}}]
Now I want to loop through the received times and print their color, how to do this?
What I've tried:
for (int i = 0; i < JArray.length(); ++i) {
JSONObject rec = null;
try {
rec = JArray.getJSONObject(i);
} catch (JSONException e) {
e.printStackTrace();
}
android.util.Log.e("print row:", String.valueOf(rec));
}
This just gives me this output:
{"06:30:00":{"color":"grey","time_color":"black"},"06:45:00":{"color":"grey","time_color":"black"}}
You are getting this output since your JSON array contains only one JSON object which is - {"06:30:00":{"color":"grey","time_color":"black"},"06:45:00":{"color":"grey","time_color":"black"}}
Before answering your question, I would recommend you to go through JSON syntax. It will help you understand your question and answer effectively.
Coming back to your question, in order to get "color" field from your nested JSON:
Traverse through keys in your JSON object. In your case these are -
"06:30:00" , "06:45:00". You can google out solution to traverse
through keys in JSON object in java.
Get nested object associated with given key(time) - you can use
getJSONObject() method provided by Json library for this.
Get "color" field from json object - you can use optString() or
getString() methods provided by Json library for this- depending
upon whether your string is mandatory or optional.
Here is working solution in java for your problem:
public static void getColor(JSONObject payloadObject) {
try {
JSONArray keys = payloadObject.names();
for (int i = 0; i < keys.length(); i++) {
String key = keys.getString(i); // Here's your key
JSONObject value = payloadObject.getJSONObject(key); // Here's your value - nested JSON object
String color = value.getString("color");
System.out.println(color);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Please note, it is considered that object you receive as payload is a JSON object.
Hope this helps.
Thanks.
Use Keys() method which return Iterator<String> so that it will be easy for iterating every nested JSON
for (int i = 0; i < JArray.length(); ++i) {
try {
JSONObject rec = JArray.getJSONObject(i);
Iterator<String> keys = rec.keys();
while(keys.hasNext()) {
String key1 = keys.next();
JSONObject nested = rec.getJSONObject(key1); //{"color":"grey","time_color":"black"}
//now again same procedure
Iterator<String> nestedKeys = nested.keys();
while(nestedKeys.hasNext()) {
String key2 = nestedKeys.next();
System.out.println("key"+"..."+key2+"..."+"value"+"..."+nested.getString(key2);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
android.util.Log.e("print row:", String.valueOf(rec));
}

Java - a better way to ignore invalid records when parsing JSON

I know that it's a bad practice to use Exceptions for flow control. But I faced the following situation: I need to parse JSON file, and if there are corrupted values for the key of a record I want to just log it and continue to parse another object from jsonArray. And even if the value is null I want to ignore it and go on.
So in my current implementation I use a try/catch block with continue. What would be a more correct approach here?
Here is how I've implemented it:
public static void parseMetrics(JSONParser parser, File jsonFile,
String metricKey, List<String> metricsList) throws IOException, ParseException {
JSONArray jsonArray = (JSONArray) parser.parse(new InputStreamReader(new FileInputStream(jsonFile)));
for (Object obj : jsonArray) {
try {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
Long metricDate = parseDate(jsonObject);
metricsList.add(new Metric(metricValue, metricDate));
} catch (java.text.ParseException e) {
continue;
log.error("Error when parsing JSON", e);
}
}
}
Actually you want to log with the error level the parsing problem.
So throwing a exception makes sense.
If the parsing error is an abnormal situation you should keep your way but just without the continue that is not convenient here :
for (Object obj : jsonArray) {
try {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
Long metricDate = parseDate(jsonObject);
metricsList.add(new Metric(metricValue, metricDate));
} catch (java.text.ParseException e) {
log.error("Error when parsing JSON", e);
}
}
But if you consider that the parsing problem is not an issue to log but a normal scenario that may happen, indeed you don't have to propagate the exception from parseDate() but you could return something like OptionalLong instead of Long.
It would give from the client side :
for (Object obj : jsonArray) {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
OptionalLong metricDate = parseDate(jsonObject);
metricDate.ifPresent(d -> metricsList.add(new Metric(metricValue, d));
}
You could also add a log in debug or info level if it makes sense.

How to get value from JSON in Android

I have JSON response:
{"error":100,"result":"{\"distance\":2.4,\"duration\":5,\"price\":0}"}
From this response I want to get a "distance" value for example. How to do it?
I tried to do like this:
String distance = String.valueOf(finalResponseDataJOSNObject.getDouble("distance"));
but string value is null. Any ideas?
UPDATE:
Finally we discovered that it was back-end issue and we fixed it. No additional operations like JSONObject conversation to String, special character removal, etc. was necessary.
Simply:
String distance =
String.valueOf(finalResponseDataJOSNObject.getJSONObject("result").getDouble("di‌​stance"));
Try this...
String json = "{\"error\":100,\"result\":{\"distance\":2.4,\"duration\":5,\"price\":0}}";
try {
JSONObject jsonObject = new JSONObject(json);
double distance = jsonObject.getJSONObject("result").getDouble(
"distance");
Log.i("DISTANCE", String.valueOf(distance));
} catch (JSONException e) {
e.printStackTrace();
}
The distance is in a JSONObject under result only. So you have to getJSONObject("result").getDouble("distance").
You can do this in following way:
Remove special character from json string and convert back to json object and process it accordingly:
String json = "{\"error\":100,\"result\":{\"distance\":2.4,\"duration\":5,\"price\":0}}";
try{
JSONObject jsonObject = new JSONObject(json.replaceAll("\"", ""));
JSONObject jsonObject2=jsonObject.getJSONObject("result");
String distance=jsonObject2.getString("distance");
double convertedDistance=Double.valueOf(distance);
Log.i("DistanceInformation", "My Distance from json is="+distance);
}catch(JSONException e)
{
e.printStackTrace();
}
Thanks for you all who responded.
Finally we discovered that it was back-end issue and we fixed it. No additional operations like JSONObject conversation to String, special character removal, etc. was necessary.
Simply:
String distance =
String.valueOf(finalResponseDataJOSNObject.getJSONObject("result").getDouble("di‌​stance"));

Categories

Resources