55

I have a json stream which can be something like :

{"intervention":

    { 
      "id":"3",
              "subject":"dddd",
              "details":"dddd",
              "beginDate":"2012-03-08T00:00:00+01:00",
              "endDate":"2012-03-18T00:00:00+01:00",
              "campus":
                       { 
                         "id":"2",
                         "name":"paris"
                       }
    }
}

or something like

{"intervention":
            [{
              "id":"1",
              "subject":"android",
              "details":"test",
              "beginDate":"2012-03-26T00:00:00+02:00",
              "endDate":"2012-04-09T00:00:00+02:00",
              "campus":{
                        "id":"1",
                        "name":"lille"
                       }
            },

    {
     "id":"2",
             "subject":"lozlzozlo",
             "details":"xxx",
             "beginDate":"2012-03-14T00:00:00+01:00",
             "endDate":"2012-03-18T00:00:00+01:00",
             "campus":{
                       "id":"1",
                       "name":"lille"
                      }
            }]
}   

In my Java code I do the following:

JSONObject json = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream     
JSONArray  interventionJsonArray = json.getJSONArray("intervention");

In the first case, the above doesn't work because there is only one element in the stream.. How do I check if the stream is an object or an array ?

I tried with json.length() but it didn't work..

Thanks

jontro
  • 10,241
  • 6
  • 46
  • 71
Tang
  • 675
  • 1
  • 7
  • 10

7 Answers7

128

Something like this should do it:

JSONObject json;
Object     intervention;
JSONArray  interventionJsonArray;
JSONObject interventionObject;

json = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream     
Object intervention = json.get("intervention");
if (intervention instanceof JSONArray) {
    // It's an array
    interventionJsonArray = (JSONArray)intervention;
}
else if (intervention instanceof JSONObject) {
    // It's an object
    interventionObject = (JSONObject)intervention;
}
else {
    // It's something else, like a string or number
}

This has the advantage of getting the property value from the main JSONObject just once. Since getting the property value involves walking a hash tree or similar, that's useful for performance (for what it's worth).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
13

Maybe a check like this?

JSONObject intervention = json.optJSONObject("intervention");

This returns a JSONObject or null if the intervention object is not a JSON object. Next, do this:

JSONArray interventions;
if(intervention == null)
        interventions=jsonObject.optJSONArray("intervention");

This will return you an array if it's a valid JSONArray or else it will give null.

Pang
  • 9,564
  • 146
  • 81
  • 122
Nathan Q
  • 1,892
  • 17
  • 40
12

To make it simple, you can just check first string from server result.

String result = EntityUtils.toString(httpResponse.getEntity()); //this function produce JSON
String firstChar = String.valueOf(result.charAt(0));

if (firstChar.equalsIgnoreCase("[")) {
    //json array
}else{
    //json object
}

This trick is just based on String of JSON format {foo : "bar"} (object) or [ {foo : "bar"}, {foo: "bar2"} ] (array)

azwar_akbar
  • 1,451
  • 18
  • 27
6

You can get the Object of the input string by using below code.

String data = "{ ... }";
Object json = new JSONTokener(data).nextValue();
if (json instanceof JSONObject)
 //do something for JSONObject
else if (json instanceof JSONArray)
 //do something for JSONArray

Link: https://developer.android.com/reference/org/json/JSONTokener#nextValue

Virendra Kachhi
  • 184
  • 1
  • 12
  • This is the best approach in my case, and also handle any response that does not fit into the two object types – William May 07 '20 at 13:37
  • This should be the correct answer, especially if you have a stream of data. Just pull nextValue and test the type. – Ralph Jan 25 '22 at 15:24
2
      Object valueObj = uiJSON.get(keyValue);
        if (valueObj instanceof JSONObject) {
            this.parseJSON((JSONObject) valueObj);
        } else if (valueObj instanceof JSONArray) {
            this.parseJSONArray((JSONArray) valueObj);
        } else if(keyValue.equalsIgnoreCase("type")) {
            this.addFlagKey((String) valueObj);
        }

// ITERATE JSONARRAY private void parseJSONArray(JSONArray jsonArray) throws JSONException { for (Iterator iterator = jsonArray.iterator(); iterator.hasNext();) { JSONObject object = (JSONObject) iterator.next(); this.parseJSON(object); } }

Sagar Jadhav
  • 1,111
  • 11
  • 10
0

I haven't tryied it, but maybe...


JsonObject jRoot = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream
JsonElement interventionElement = jRoot.get("intervention");
JsonArray interventionList = new JsonArray();

if(interventionElement.isJsonArray()) interventionList.addAll(interventionElement.getAsJsonArray());
else interventionList.add(interventionElement);

If it's a JsonArray object, just use getAsJsonArray() to cast it. If not, it's a single element so just add it.

Anyway, your first exemple is broken, you should ask server's owner to fix it. A JSON data structure must be consistent. It's not just because sometime intervention comes with only 1 element that it doesn't need to be an array. If it has only 1 element, it will be an array of only 1 element, but still must be an array, so that clients can parse it using always the same schema.

0
    //returns boolean as true if it is JSONObject else returns boolean false 
public static boolean returnBooleanBasedOnJsonObject(Object jsonVal){
        boolean h = false;
        try {
            JSONObject j1=(JSONObject)jsonVal;
            h=true;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
   if(e.toString().contains("org.json.simple.JSONArray cannot be cast to     org.json.simple.JSONObject")){
                h=false;
            }
        }
        return h;

    }
haroon
  • 1