1

I am receiving json and am trying to operate on it using the JSONObject and JSONArray classes. I have nested objects and need to determine if those nested objects are arrays or objects. The problem is that if I assume it is an object and it is actually an array, when I get call getJSONObject, an exception is raised. I'm wondering if the only way to do this is just to add try/catch blocks or if there is a better way to do this. For example, say I have:

{"key1": "val1",
 "key2": {"level2": {"level3": "val3"}}
}

I may also have the level2 element with multiple values and coming in as an array:

{"key1": "val1",
 "key2": {"level2": [{"level3": "val3"}]}
}

How would I extract the level2 object (as an object) and determine if it is an object or an array? Is the only way to really do this using string manipulation?

If I do something like:

jsonObj.getJSONObject("key2").getJSONObject("level2");

It will result in an error: "org.json.JSONException: JSONObject["level2"] is not a JSONObject and conversly, if I call getJSONArray("level2") and level2 is not an array I will get an error indicating it is not an array.

5
  • 1
    I think the solution here is to name the keys better and just know what you're trying to parse beforehand. In other words, have a consistent schema Commented Sep 16, 2017 at 17:33
  • The problem is that the json is coming from an XML to JSON converter and if the json schema is intended to have an element as an array, but the element only has a single element, the converter has no way to know that the single element is intended to be just an object or a single element in an array. Commented Sep 16, 2017 at 18:48
  • which library you are using for json parsing Commented Sep 16, 2017 at 19:44
  • The converter should know the difference between a single element array and an object. Commented Sep 16, 2017 at 20:37
  • org.json library Commented Sep 16, 2017 at 21:17

4 Answers 4

2

You can use optJSONObject() & optJSONArray() methods to check if the underlying is an Object or Array. Below is an example for that.

JSONObject json = new JSONObject("{\"key1\": \"val1\",\n" + 
        " \"key2\": {\"level2\": {\"level3\": \"val3\"}}\n" + 
        "}");

JSONObject json1 = new JSONObject("{\"key1\": \"val1\",\n" + 
        " \"key2\": {\"level2\": [{\"level3\": \"val3\"}]}\n" + 
        "}");

if(json.getJSONObject("key2").optJSONObject("level2") != null) {
    System.out.println("json : it is a jsonobject");
}
else if(json.getJSONObject("key2").optJSONArray("level2") != null) {
    System.out.println("json : it is a jsonarray");
}


if(json1.getJSONObject("key2").optJSONObject("level2") != null) {
    System.out.println("json1 : it is a jsonobject");
}
else if(json1.getJSONObject("key2").optJSONArray("level2") != null) {
    System.out.println("json1 : it is a jsonarray");
}
Sign up to request clarification or add additional context in comments.

2 Comments

Excellent...that's what I was looking for. Thanks so much.
Glad that it helped!
0

Use 'jsonObj.get("level2)' and check whether the type is JsonArray and then try to cast it.

1 Comment

Can't do that. I got JSONException: JSONObject["level2"] not found. I assume this is because it is an embedded object and I would need some way to refer to key2.level2 in the "get" method. If there was a way to reference a nested object using the "get" method I think this would be the best way.
0

If you're open to using Jackson's Databind module, it's pretty straightforward:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

// ...

// parse your JSON data into a JsonNode
JsonNode jsonObj = new ObjectMapper().readTree(yourJsonString);

// should really do some error checking here unless you're 100% sure
// you're always going to be getting "key2" and "level2" in your JSON
// data structure; look into Jackson's "hasNonNull()" function
JsonNode level2 = jsonObj.get("key2").get("level2");

if (level2.isArray()) {
    ArrayNode level2arr = (ArrayNode)level2;
    // ... do something with level2arr as an array
    // ...
} else if (level2.isObject()) {
    // ... use it as an object node
    // ...
}

Comments

0

I would stringify the JSON object and check the index of '{' or '['.

Given a Json, I would stringify it. And if the index of '{' is 0 in the stringified object then its a Json Object and if the index of '[' is 0 in the stringified object then its a Json Array.

I use Vertx framework and I can verify them as follows:

JsonObject jsonObject = new JsonObject().put("name", "avishek");
JsonArray jsonArray = new JsonArray().add("Vizury").add("MediaIQ");

System.out.println(jsonObject.toString().indexOf("{") == 0); //Json Object
System.out.println(jsonArray.toString().indexOf("[") == 0); //Json Array

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.