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
.