androidjsonandroid-volleynested-loopsjsonobjectrequest

Iterate and parse nested JSON Objects with Android VOLLEY


I am retrieving a JSON Object via the Volley class in Android. Getting the request works great. However, I am really struggling to parse this giant object. In PHP, the loop looks something like:

foreach($json['data'][0]['region'][0]['pool'] as $item) { 
   $serve_mode = $item['serve_mode'];
   $address = $item['address'];
   $label = $item['label']; 
}

Based on my JSON, that gives me 3 sets of data total.

The snippet of JSON I am grabbing from:

{
    "data": {
        "active": "Y",
        "auto_recover": "Y",
        "contact_nickname": "owner",
        "fqdn": "example.com",
        "monitor": {
            "expected": "",
            "header": "",
            "host": "www.example.com",
            "interval": 5,
            "path": "/hello.php",
            "port": 0,
            "protocol": "HTTPS",
            "retries": 3,
            "timeout": 0
        },
        "notify_events": "svc,ip,nosrv",
        "recovery_delay": 0,
        "region": [
            {
                "failover_data": "12.345.678.90",
                "failover_mode": "ip",
                "min_healthy": 1,
                "pool": [
                    {
                        "address": "67.890.123.45",
                        "label": "SomeCompany Circuit A",
                        "log": [
                            {
                                "message": "",
                                "site_code": "DFW",
                                "status": "up",
                                "time": 1605843120
                            },
                            {
                                "message": "",
                                "site_code": "IAD",
                                "status": "up",
                                "time": 1605843120
                            },
                            {
                                "message": "",
                                "site_code": "MIA",
                                "status": "up",
                                "time": 1605843120
                            }
                        ],
                        "serve_mode": "obey",
                        "status": "up",
                        "weight": 2
                    },
                    {
                        "address": "34.567.89.012",
                        "label": "SomeCompany Circuit B",
                        "log": [
                            {
                                "message": "",
                                "site_code": "DFW",
                                "status": "up",
                                "time": 1605843120
                            },
                            {
                                "message": "",
                                "site_code": "IAD",
                                "status": "up",
                                "time": 1605843120
                            },
                            {
                                "message": "",
                                "site_code": "MIA",
                                "status": "up",
                                "time": 1605843120
                            }
                        ],
                        "serve_mode": "obey",
                        "status": "up",
                        "weight": 1
                    },
                    {
                        "address": "12.345.678.90",
                        "label": "SomeCompany Circuit C",
                        "log": [
                            {
                                "message": "",
                                "site_code": "MIA",
                                "status": "up",
                                "time": 1605843120
                            },
                            {
                                "message": "",
                                "site_code": "DFW",
                                "status": "up",
                                "time": 1605843120
                            },
                            {
                                "message": "",
                                "site_code": "IAD",
                                "status": "up",
                                "time": 1605843120
                            }
                        ],
                        "serve_mode": "obey",
                        "status": "up",
                        "weight": 2
                    }
                ],
                "region_code": "global",
                "serve_count": 1
            }
        ],

I am not getting deep enough into the JSON Object, and I am unsure of how to get the index 0 in those two arrays (as you can see in the PHP example. So far, I have gotten all the way down to the pool level, but no further.

The onResponse portion of my Volley request:

    @Override
    public void onResponse(JSONObject response) {
      try {
        JSONObject data = response.getJSONObject("data");
        JSONArray region = data.getJSONArray("region");
        JSONObject pool = region.getJSONObject(0);
        JSONArray item = pool.getJSONArray("pool");
        
        Log.d(TAG, "item: "+item);

      } catch (JSONException e) {
          e.printStackTrace();
          Log.d(TAG, "JSONException: "+e.toString());
    }
   
  }
}

It gives me:

[{
    "status": "up",
    "log": [{
        "status": "up",
        "message": "",
        "site_code": "DFW",
        "time": 1605848520
    }, {
        "status": "up",
        "message": "",
        "site_code": "IAD",
        "time": 1605848520
    }, {
        "status": "up",
        "message": "",
        "site_code": "MIA",
        "time": 1605848520
    }],
    "weight": 2,
    "serve_mode": "obey",
    "address": "67.890.123.45",
    "label": "SomeCompany Circuit A"
}, {
    "status": "up",
    "log": [{
        "status": "up",
        "message": "",
        "site_code": "DFW",
        "time": 1605848520
    }, {
        "status": "up",
        "message": "",
        "site_code": "IAD",
        "time": 1605848520
    }, {
        "status": "up",
        "message": "",
        "site_code": "MIA",
        "time": 1605848520
    }],
    "weight": 1,
    "serve_mode": "obey",
    "address": "34.567.890.12",
    "label": "SomeCompany Circuit B"
}, {
    "status": "up",
    "log": [{
        "status": "up",
        "message": "",
        "site_code": "MIA",
        "time": 1605848520
    }, {
        "status": "up",
        "message": "",
        "site_code": "DFW",
        "time": 1605848520
    }, {
        "status": "up",
        "message": "",
        "site_code": "IAD",
        "time": 1605848520
    }],
    "weight": 2,
    "serve_mode": "obey",
    "address": "12.234.567.890",
    "label": "SomeCompany Circuit C"
}]

A visual representation of what I'm needing looks like this:

enter image description here

Basically I need all the way down to pool, and those 3 strings from each. How in the world do I achieve this? It was alright in PHP, but geeze this has become a rabbit hole, and I'm struggling to get this information on my app screen.


Solution

  • I'm going to make these strings member variables, but for now, I created them in my onResponse method. I was almost there. I just needed to iterate over the final JSONArray to get the values.

    String serve_mode = "";
    String address = "";
    String label = "";
    String weight = "";
    try {
      JSONObject data = response.getJSONObject("data");
      JSONArray region = data.getJSONArray("region");
      JSONObject pool = region.getJSONObject(0);
      JSONArray item = pool.getJSONArray("pool");
    
      //NOW ITERATE OVER THE NESTED ARRAY "pool"
      for(int i = 0; i < item.length(); i++) {
        JSONObject pool_item = item.getJSONObject(i);
        serve_mode = pool_item.getString("serve_mode");
        address = pool_item.getString("address");
        label = pool_item.getString("label");
        weight = pool_item.getString("weight");
    
        Log.d(TAG, "serve_mode: "+serve_mode);
        Log.d(TAG, "address: "+address);
        Log.d(TAG, "label: "+label);
        Log.d(TAG, "weight: "+weight);
      }
    } catch (JSONException e) {
        Log.d(TAG, "JSONException: "+e.toString());
      }
    

    This yields (address and label fields were edited):

    D/MainActivity: serve_mode: obey
    D/MainActivity: address: 12.345.678.90
    D/MainActivity: label: SomeCompany A
    D/MainActivity: weight: 2
    D/MainActivity: serve_mode: obey
    D/MainActivity: address: 123.456.789.01
    D/MainActivity: label: SomeCompany B
    D/MainActivity: weight: 1
    D/MainActivity: serve_mode: obey
    D/MainActivity: address: 456.789.012.34
    D/MainActivity: label: SomeCompany C
    D/MainActivity: weight: 2