0

Im working with an android app where i receive a json based response from a webservice. All was fine when the webservice returned more than one record in response as json array, the issue started when the web service started sending data which had only one record and it was sent as json object.On the client side i cant predict the number of records being returned(like 1 or more than 1) i want to find a solution which accommodates both conditions. The below code is the one i use to aprse the data when there are more than one records,

get_response = new JSONObject(webservice_out);
JSONArray inventory_data = get_response.getJSONArray("inventorydata");
Log.e("inventory", inventory_data.toString());
for (int j = 0; j < inventory_data.length(); j++)
{
    JSONObject e1 = inventory_data.getJSONObject(j);
    Log.e("names", e1.getString("itemName"));
    JSONObject e3 = e1.getJSONObject("passenger");              
}

In the above code "inventorydata" is one of the json value returned as a response from the webservice, whenever "inventorydata" hold only one record in response its being sent as json object, when it has more than 1 records its being sent as json array. Since the number of records in the response are dynamic , i want to find a solution which can hold both (json object and array) depending the response from the webservie.

Note: i dont have any authority to make changes to the webservice

  • 1
    you can always test the first character. `[` would mean array, `{` would mean object. You can also try to parse as one type, catch the exception and fall back on the other type. – njzk2 May 14 '14 at 13:40
  • @njzk2 thats the only solution i have right now if nothing else works, is it psoosible to convert the json object into json so that my working can be left untouched – bala_gamer May 14 '14 at 13:42
  • @AleksG will look into that thread, my json response is a nested one so testing the 1st character for [ or { alone wont be enough. – bala_gamer May 14 '14 at 13:45
  • 1
    @AleksG this is not correct. JSONArray is not extending JSONObject. – hgoebl May 14 '14 at 13:52

1 Answers1

2

You have two options:

  1. Tell your server team to always send a json array, even if it only contains one item. This is the preferred solution because it enforces that the structure of the response does not change and allows clients to process it the same way every time.
  2. Use get_response.optJSONArray() instead, then check if it's null. If it is, fall back to getJSONObject().

    JSONArray inventory_data = get_response.optJSONArray("inventorydata");
    
    if (inventory_data == null) {
        // process json array
    } else {
        JSONObject jsonObject = get_response.getJSONObject("inventorydata");
        // process json object
    }
    
TheMohanAhuja
  • 1,855
  • 2
  • 19
  • 30
Karakuri
  • 38,365
  • 12
  • 84
  • 104
  • #1: For security reasons JSON arrays shouldn't be used as root objects. Option #2 would be my preferred solution. – hgoebl May 14 '14 at 14:02
  • 1
    @hgoebl Please explain the security concern? – Karakuri May 14 '14 at 14:03
  • http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/ – hgoebl May 14 '14 at 14:04
  • I don't think he has a JSON array as the root element. The OP suggests a structure like `{ "inventory_data":{...} }` for single item or `{ "inventory_data":[ {...}, {...} ] }` for miltiple items – Karakuri May 14 '14 at 14:36
  • you're right, the array is in an object. So my comments are not appropriate in this case. +1 for your answer... – hgoebl May 14 '14 at 16:22
  • @Karakuri you are right,the root is not a json array – bala_gamer May 15 '14 at 04:51
  • @Karakuri i tried your suggestion, but it straight away throws json exception on the 1st line JSONArray inventory_data = get_response.optJSONArray("inventorydata"); – bala_gamer May 15 '14 at 05:03
  • If `getJSONArray` worked before, then `optJSONArray` should have also worked, so I'm puzzled as to why it would throw an exception. Please find the stack trace and post it. – Karakuri May 15 '14 at 14:32