0

I am looking to create an ArrayList of custom objects from a JSON feed using GSON. My current approach works fine for a single JSON object holding an array, but now I need to parse a more complex JSON object. The first JSON feed looked like this:

{"data": 
    {"item_id": "1", "element": "element1"}
    {"item_id": "2", "element": "element2"}
    {"item_id": "3", "element": "element3"}
    ...
}

My method for extracting each item was using a simple custom object and parsing the JSON into an ArrayList of these objects.

InputStreamReader input = new InputStreamReader(connection.getInputStream());

Type listType = new TypeToken<Map<String, ArrayList<CustomObject>>>(){}.getType();
Gson gson = new GsonBuilder().create();
Map<String, ArrayList<CustomObject>> tree = gson.fromJson(input, listType);
ArrayList<CustomObject> = tree.get("data");

The current JSON object looks like this:

{"rate_limit": 1, "api_version": "1.2", "generated_on": "2015-11-05T19:34:06+00:00", "data": [
    {"collection": [
        {"item_id": "1", "time": "2015-11-05T14:40:55-05:00"},
        {"item_id": "2", "time": "2015-11-05T14:49:09-05:00"},
        {"item_id": "3", "time": "2015-11-05T14:51:55-05:00"}
    ], "collection_id": "1"},
    {"collection": [
        {"item_id": "1", "time": "2015-11-05T14:52:01-05:00"},
        {"item_id": "2", "time": "2015-11-05T14:49:09-05:00"},
        {"item_id": "3", "time": "2015-11-05T14:51:55-05:00"}
    ], "collection_id": "2"
]}

And I am having trouble parsing it because of the mixed types of data, some are numbers, strings and lastly arrays. I have a custom object built that takes an array of another custom object. This is the collection object:

public class CustomCollection {
    private String collection_id;
    private ArrayList<CustomItem> collection_items = new ArrayList<>();

    public CustomCollection() {
        this(null, null);
    }

    public CustomCollection(String id, ArrayList<CustomItem> items) {
        collection_id = id;
        collection_items = items;
    }

    public String getId() {
       return collection_id;
    }

    public ArrayList<CustomItem> getItems() {
        return collection_items;
    }
}

And this is the item object:

public class CustomItem {
    private String item_id;
    private String item_element;

    public CustomItem() {
        this(null, null);
    }

    public CustomItem(String id, String element) {
        item_id = id;
        item_element = element;
    }

    public String getId() {
        return item_id;
    }

    public String getElement() {
        return item_element;
    }
}

I do not really care about obtaining the other elements (i.e. "rate_limit", "api_version", "generated_on"), I just want to pass the "data" element into an ArrayList of objects. But when I try something similar to my original method, the parser stops a the first object because it receives a number instead of an array. Resulting in an IllegalStateException: Expected BEGIN_ARRAY but was NUMBER at line 1 column 17 path $.. I would like to know how I can either get the parser to ignore the other elements, or how I can get each element separately using GSON.

EDIT: The proposed solution to my problem, found in Ignore Fields When Parsing JSON to Object, technically does solve my issue. But this seems like a lengthy process that is unnecessary in my case. I have found a much simpler solution to my problem, posted in my answer below. I am also unsure if this method would work well for the aforementioned question, considering there does not seem to be a way to get a JsonObject from a JsonArray by key name in GSON.

Community
  • 1
  • 1
Bryan
  • 14,756
  • 10
  • 70
  • 125
  • Possible duplicate of [Gson - ignore json fields when parsing JSON to Object](http://stackoverflow.com/questions/28423292/gson-ignore-json-fields-when-parsing-json-to-object) – JstnPwll Nov 05 '15 at 20:21
  • 1
    use volley library instead of using standard network requests. – Rushi Ayyappa Nov 06 '15 at 15:10
  • @RushiAyyappa This does not directly resolve my issue, but it helped with my app immeasurably. I did not know that the `Volley` library even existed, I feel like Google should make it more apparent, especially since (after doing some research) `AsyncTask` is considered pretty lousy. Anyway, I ended up using `RetroFit` from Square instead, I hear it is even faster and more lightweight than `Volley`. But thank you, this has put me on a much easier path. – Bryan Nov 11 '15 at 14:18
  • 1
    welcome.Happy Coding!! @Bryan – Rushi Ayyappa Nov 12 '15 at 08:34

1 Answers1

0

The solution I have found is to parse the data into a com.google.gson.JsonObject, then into a JsonArray by key name. I can then use this JsonArray as a parameter in Gson.fromJson() to extract the data into my ArrayList of custom objects.

InputStreamReader input = new InputStreamReader(connection.getInputStream());

JsonArray data = new JsonParser().parse(input).getAsJsonObject().getAsJsonArray("data");

Type listType = new TypeToken<ArrayList<CustomCollection>>(){}.getType();
ArrayList<CustomCollection> collection = new Gson().fromJson(data, listType);

input.close();

This method ignores all other JSON fields, only obtaining the one specified. It also takes the array of objects from within the "data" object and puts them into the ArrayList of custom objects within CustomCollection.

Bryan
  • 14,756
  • 10
  • 70
  • 125