How to Parse Nested / Multiple Json Objects using Retrofit

2.8k views Asked by At

The JSON I'm parsing looks like this:

{   "version": 1
    "data": {
        "1001": {
          "id": 1001,
          "name": "herp",
          "into": [
            "3111": "we"
          ]
        }, 
        "1032": {
          "id": 1002,
          "name": "derp",
          "into": [
            "36": "w",
            "12341: "c"
          ],
          "tags": [
            "hi there"
          ],
          "cost" {
            "even": 15
          }
        }, 
        "1603": {
          "id": 1003,
          "name": "her",
          "into": [
            "37": "dll",
            "58": "eow",
            "32145": "3a"
          ],
          "cost" {
            "highest": 325
            "lowest": 100
          }
        }, 
        .... Even more data
}

The Json that is within "data" goes on for a while and does not have a set endpoint. I have no control over the Json, I'm just trying to read it. Unfortunately, with my class code I'm unable to get it to work. When I make a retrofit call the information inside "data" is empty.

I've tried many iterations of implementing this, including using a deserializer and restructuring my POJO code. This is the current state of my Data class:

public class Data {

  private Map<String, Item> itemData;

  // Relevant Getters, Setters and Constructors //
}

For my Item Class, the main issue is that the JSON Content isn't set, it can vary at times. As you can see above the values inside "into" vary and sometimes the amount of things within item changes as well such as "tags" or "cost":

public class Item {

  private int id;
  private String name;
  private String group;
  private String description;
  private Map<String, String> into;
  private List<String> tags;
  private Map<String, Integer> cost;

  // Relevant Getters, Setters and Constructors //

When I use this code my data class is empty, I don't see any errors in the log so I can't seem to figure out why the GSON isn't working with this.

In case you wanted to see how I construct my RestClient, here it is:

RestAdapter.Builder builder = new RestAdapter.Builder()
        .setEndpoint(ROOT)
        .setClient(new OkClient(new OkHttpClient()))
        .setLogLevel(RestAdapter.LogLevel.FULL);

RestAdapter restAdapter = builder.build();
REST_CLIENT = restAdapter.create(DataApi.class);

I know that my Rest Query works because I can get the content within "version" but everything inside data is null.

2

There are 2 answers

0
Tiensi On BEST ANSWER

I am officially a dumb scrub and completely looked over the easiest possible fix and should have my account and developer title revoked.

This is all I should have done:

public class ItemGroup {

  private String version;
  private Map<String,Item> data;

    //...Man i'm so dumb...
}

AS REFERENCE FOR THE FUTURE. The reason why this works is because the JSON is in this format { { } { } { } }. Which means you have 3 objects of objects, as opposed to { [ ] [ ] [ ] } which is 3 objects of a list. What I had done was treat { { } { } { } } as { { { } { } { } } }. Which is not correct. By using a map which is basically a collection of pairs, we are able to imitate the { { } { } { } } with a Map.

Map Object { {Key-Pair Object} {Key-Pair Object} {Key-Pair Object} }

3
Fabian On

Just a quick idea for your Pojos: Not sure if this will work. Maybe write a custom deserializer.

public class YourResponse {
    int version;
    Data data;

    class Data {
        Subdata subData;
    }

    class Subdata {
        private int id;
        private String name;
        private ArrayList<Into> into;
        private ArrayList<String> tags;
        //...
    }

    class Into {
        // "3111": "we"
        private String into;
    }
}