21

I am getting JSON string from website. I have data which looks like this (JSON Array)

 myconf= {URL:[blah,blah]}

but some times this data can be (JSON object)

 myconf= {URL:{try}}

also it can be empty

 myconf= {}    

I want to do different operations when its object and different when its an array. Till now in my code I was trying to consider only arrays so I am getting following exception. But I am not able to check for objects or arrays.

I am getting following exception

    org.json.JSONException: JSONObject["URL"] is not a JSONArray.

Can anyone suggest how it can be fixed. Here I know that objects and arrays are the instances of the JSON object. But I couldn't find a function with which I can check whether the given instance is a array or object.

I have tried using this if condition but with no success

if ( myconf.length() == 0 ||myconf.has("URL")!=true||myconf.getJSONArray("URL").length()==0)
Judy
  • 1,533
  • 9
  • 27
  • 41

5 Answers5

54

JSON objects and arrays are instances of JSONObject and JSONArray, respectively. Add to that the fact that JSONObject has a get method that will return you an object you can check the type of yourself without worrying about ClassCastExceptions, and there ya go.

if (!json.isNull("URL"))
{
    // Note, not `getJSONArray` or any of that.
    // This will give us whatever's at "URL", regardless of its type.
    Object item = json.get("URL"); 

    // `instanceof` tells us whether the object can be cast to a specific type
    if (item instanceof JSONArray)
    {
        // it's an array
        JSONArray urlArray = (JSONArray) item;
        // do all kinds of JSONArray'ish things with urlArray
    }
    else
    {
        // if you know it's either an array or an object, then it's an object
        JSONObject urlObject = (JSONObject) item;
        // do objecty stuff with urlObject
    }
}
else
{
    // URL is null/undefined
    // oh noes
}
cHao
  • 84,970
  • 20
  • 145
  • 172
  • Thanks. I have edited my question may be it will make more sense what I am wondering about. Can you give example for if (item instanceof JSONArray). What should I put in if condition? – Judy Mar 22 '12 at 06:34
  • That *is* the example. The `instanceof` operator will tell you if `item` is a `JSONArray`. Hold on, lemme flesh it out a bit. – cHao Mar 22 '12 at 06:41
  • Thanks Chao. Actually it worked. But the string can be empty also. So I am getting error for that also. if(!myconf.isNull("URL")||(myconf.getJSONArray("URL")!=null)||myconf.getJSONArray("URL").length()>0) {Object item = myconf.get("URL"); //other code} I am getting exception JSONObject["URL"] not found. – Judy Mar 22 '12 at 06:57
  • @Judy: What do you mean by "the string can be empty"? – cHao Mar 22 '12 at 06:57
  • Actually I have edited the question also. I mean the Json contains nothing i.e. myconf= { } Hence there will be no URL also in the string. – Judy Mar 22 '12 at 07:00
  • K, first off, quit stuffing everything on one line. You're going to have to do different stuff based on whether it's null, or an array, or an object, right? Well, a boolean can only have two states, and you have three possible outcomes. Break things up a little. – cHao Mar 22 '12 at 07:02
  • You're from the "Braces-At-New-Line" guild.... You shall not pass! – Magno C Nov 26 '19 at 18:43
  • 1
    @MagnoC: Haven't been for years. :) I just don't believe in editing posts to reflect such trivialities. – cHao Nov 28 '19 at 00:03
10

Quite a few ways.

This one is less recommended if you are concerned with system resource issues / misuse of using Java exceptions to determine an array or object.

try{
 // codes to get JSON object
} catch (JSONException e){
 // codes to get JSON array
}

Or

This is recommended.

if (json instanceof Array) {
    // get JSON array
} else {
    // get JSON object
}
Oh Chin Boon
  • 23,028
  • 51
  • 143
  • 215
  • Thanks, I know how to remove exceptions. I am concerned about checking the contents of the object and checking whether URL is array or an object. – Judy Mar 22 '12 at 06:17
  • 1
    Yep, if you hit an exception trying to get an object when it is a JSON array, then you provide the implementation to get an array in the catch clause. This is one way though not recommended. – Oh Chin Boon Mar 22 '12 at 06:19
  • Actually I am looking for a function which can be used in if condition for the check. – Judy Mar 22 '12 at 06:22
8

I was also having the same problem. Though, I've fixed in an easy way.

My json was like below:

[{"id":5,"excerpt":"excerpt here"}, {"id":6,"excerpt":"another excerpt"}]

Sometimes, I got response like:

{"id":7, "excerpt":"excerpt here"}

I was also getting error like you. First I had to be sure if it's JSONObject or JSONArray.

JSON arrays are covered by [] and objects are with {}

So, I've added this code

if (response.startsWith("[")) {
  //JSON Array
} else {
  //JSON Object 
}

That worked for me and I wish it'll be also helpful for you because it's just an easy method

See more about String.startsWith here - https://www.w3schools.com/java/ref_string_startswith.asp

codyfraley
  • 99
  • 3
  • 12
AA Shakil
  • 538
  • 4
  • 14
2

The below sample code using jackson api can be used to always get the json string as a java list. Works both with array json string and single object json string.

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonDataHandler {
    public List<MyBeanClass> createJsonObjectList(String jsonString) throws JsonMappingException, JsonProcessingException {
        ObjectMapper objMapper = new ObjectMapper();
        objMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        List<MyBeanClass> jsonObjectList = objMapper.readValue(jsonString, new TypeReference<List<MyBeanClass>>(){});
        return jsonObjectList;
    }
}
0

Using @Chao answer i can solve my problem. Other way also we can check this.

This is my Json response

{
  "message": "Club Details.",
  "data": {
    "main": [
      {
        "id": "47",
        "name": "Pizza",

      }
    ],

    "description": "description not found",
    "open_timings": "timings not found",
    "services": [
      {
        "id": "1",
        "name": "Free Parking",
        "icon": "http:\/\/hoppyclub.com\/uploads\/services\/ic_free_parking.png"
      } 
    ]
  }
}

Now you can check like this that which object is JSONObject or JSONArray in response.

String response = "above is my reponse";

    if (response != null && constant.isJSONValid(response))
    {
        JSONObject jsonObject = new JSONObject(response);

        JSONObject dataJson = jsonObject.getJSONObject("data");

        Object description = dataJson.get("description");

        if (description instanceof String)
        {
            Log.e(TAG, "Description is JSONObject...........");
        }
        else
        {
            Log.e(TAG, "Description is JSONArray...........");
        }
    }

This is used for check that received json is valid or not

public boolean isJSONValid(String test) {
        try {
            new JSONObject(test);
        } catch (JSONException ex) {
            // e.g. in case JSONArray is valid as well...
            try {
                new JSONArray(test);
            } catch (JSONException ex1) {
                return false;
            }
        }
        return true;
    }
Farmer
  • 4,093
  • 3
  • 23
  • 47