Meh
Meh

Reputation: 51

Java GSON - Serialize & Deserialize Class with generics type List

Example classes:

public class A
{
    String Name;
    List<B> GenericsList;

    //Getters & Setters & Constructors
}

public class B
{
   String Title;
   //Getters & Setters & Constructors
}

public class C extends B
{
    String Something;
    //Getters & Setters & Constructors
}

If i serialize an instance of class A like this:

List<B> bList = new ArrayList<>();
C bObj = new C("name", "something text");
bList.add(bObj);

A aObj = new A("name", bList);

String serialized = new Gson.toJson(aObj);

A deserializedA = new Gson.fromJson(serialized);

I lose the C subtype in the List. I know how to work around this if its just a List to serialize like this:

Gson gson = new Gson();
List<B> bList = new ArrayList<>();

Type bType = new TypeToken<List<B>>() {}.getType();
gson.toJson(bList, bType);

gson.fromJson(json, bType);

The problem is that my generics list is inside an object with other parameters. How do i do this?

Edit 1: Maybe i was not clear about the concrete problem.

When i serialize and deserialize the created A object above there is no error but instead of getting this: Object A: Name = "name" GenericsList = {Object C}

i get: Object A: Name = "name" GenericsList = {Object B}

i lose the subtype C detail.

Upvotes: 2

Views: 4859

Answers (1)

Meh
Meh

Reputation: 51

Got it! Thanks for the tip Sotirios Delimanolis!

Had to create a custom implementation for the B class:

class BGsonAdapter implements JsonSerializer<B>, JsonDeserializer<B>
{
    public JsonElement serialize(B bObj, Type typeOfSrc, JsonSerializationContext context)
    {
        JsonObject result = new JsonObject();
        result.add("Title", context.serialize(B.getTitle(), String.class));

        if (bObj instanceof C)
        {
            result.add("Something", context.serialize(((C)bObj).getSomething(), String.class));
        }

        return result;
    }

    public B deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
    {
        JsonObject object = json.getAsJsonObject();
        B result = null;

        if (object.has("Something"))
        {
            result = new C();
            ((C) result).setSomething((String)context.deserialize(object.get("Something"), String.class));

        if (result == null)
        {
            result = new B();
        }
        result.setTitle(((String)context.deserialize(object.get("Title"), String.class)));

        return result;
    }
}

and use it like this:

Gson gson = new GsonBuilder()
            .registerTypeHierarchyAdapter(B.class, new BGsonAdapter())
            .setPrettyPrinting()
            .create();

String serialized = gson.toJson(A);

A deserialized = (A)gson.fromJson(A);

Upvotes: 2

Related Questions