Psest328
Psest328

Reputation: 6675

GSON - 1 parent, multiple children

In the below JSON, you'll see that there are many objects that have a 'groups' child (these all seem to be the same), and that those groups have a child named 'items' (these are different depending on the group's parent).

My question:

is it possible to make 1 'groups' class that's added to multiple objects but still have the correct 'items' class be parsed by GSON?

Maybe something like:

public List<Item<T>> items

not sure how to go about this and trying to avoid writing a ton of redundant 'groups' classes.

Thanks in advance!

Pasting the JSON string put me over the character limit so I posted it up on pastebin. You can find it by clicking here

Upvotes: 0

Views: 2417

Answers (1)

Carlo Moretti
Carlo Moretti

Reputation: 2250

The problem with the JSON you're trying to deserialize is that it contains mixed elements as groups items thus it is impossible to just write a POJO to fit that structure.

In fact you'll have at some point a field like this:

ArrayList<Group> groups;

But Group can change actual type from item to item in the list, so what you can do at this point is to build a general father GenericGroup<T> class like this:

public class GenericGroup<T> {

    String type;
    String name;
    ArrayList<T> items;

    public ArrayList<T> getItems(){
        return items;
    }

    public static class SomeGroup extends GenericGroup<SomeItem>{}
    public static class SomeOtherGroup extends GenericGroup<SomeOtherItem>{}

}

Done this, you should then put in the POJO model for the JSON the field:

ArrayList<GenericGroup> groups;

Now you're ready to create items of each type you need like:

public class SomeItemType{

    String someAttribute;
    String someOtherAttribute;
    ...

}

Now comes the crazy part where you'll need to write a custom GSON deserializer for the class GenericGroup:

public class GenericGroupDeserializer implements JsonDeserializer<GenericGroup> {
    @Override
    public GenericGroup deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        String type = json.getAsJsonObject().get("type").getAsString();
        switch (type){
            case "someType":
                return new Gson().fromJson(json.toString(), GenericGroup.SomeGroup.class);
            case "someOtherType":
                return new Gson().fromJson(json.toString(), GenericGroup.SomeOtherGroup.class);
            default:
                return new GenericGroup();
        }
    }
}

Then finally, in your MainActivity write something like this:

private Gson mGson = new GsonBuilder()
            .registerTypeHierarchyAdapter(GenericGroup.class, new GenericGroupDeserializer()).create();

Upvotes: 1

Related Questions