Home > Back-end >  Mapping part of a JSON string to an abstract class using GSON
Mapping part of a JSON string to an abstract class using GSON

Time:07-03

I have a json string that I would like to map to my java object. I am currently using gson to do so. The problem is however, I have setup part of my POJO to contain an abstract class. How can I map the json that corresponds to this abstract class correctly?

To clarify:

Here is an example of a json string I am currently receiving:

{
    "Items" : [
        {
            "id" : "ID1",
            "seller_id": 17, 
            "item_plan": {
                "action" : "Sell"
            }
        },
        {
            "id" : "ID2",
            "seller_id": 27, 
            "item_plan": {
                "action": "Remove",
            }
        }
    ]
}

My request object is setup like so:

public class RequestObject {

    @SerializedName("Items")
    @Expose
    private List<Item> items = null;

public class Item {
    @SerializedName("id")
    @Expose
    private String id;
   
    @SerializedName("seller_id")
    @Expose
    private Integer sellerID;

    @SerializedName("item_Plan")
    @Expose
    private ItemPlan item_plan;

public abstract class ItemPlan {
    @SerializedName("action")
    @Expose
    private String action;

    public abstract void executePlan()

As you can see, my request object has an abstract class that represents item_plan. The idea here is that item_plan actions will have their own way of execution and therefore have a parent class called ItemPlan where each child class would represent the possible action plans and their own executionPlan ie. (SellPlan is a child class of ItemPlan, where SellPlan has its own implementation of the function executionPlan()).

How can I map my example json string to the following Java classes?

I have tried the following:

RuntimeTypeAdapterFactory<ItemPlan> itemPlanRuntimeTypeAdapterFactory =
                RuntimeTypeAdapterFactory
                .of(ItemPlan.class, "action")
                .registerSubtype(SellPlan.class, "Sell")
                .registerSubtype(RemovePlan.class, "Remove");

Gson gson = new 
GsonBuilder().registerTypeAdapterFactory(itemPlanRuntimeTypeAdapterFactory).create();
        
RequestObject request = gson.fromJson(jsonString, RequestObject.class);

This, however, does not work. It is able to map everything I need but it fails to create the correctly create the abstracted class objects ie. while it will create the corresponding child objects (SellPlan for Sell and RemovePlan for Remove), it will make the action string of those classes null. There is a workaround where I can simply set the action string manually in the constructor of these classes but I would rather not. Is there a way to fix this?

Thank you.

CodePudding user response:

You probably have to use the RuntimeTypeAdapterFactory.of overload with the additional maintainType parameter for which you then pass true as value. Otherwise, as you have noticed, Gson removes the type field value during serialization, and therefore the field keeps its default value null.

  • Related