如何使用Gson将Json响应映射到Retrofit中的抽象类?

时间:2018-04-10 08:25:56

标签: java gson retrofit2

我需要使用Retrofit实现一个Web服务,它返回一个json并映射到Java Class。问题是在json响应中将包含一个属性,它将根据对象的类型更改细节。每种类型都有自己的指定模型,因此不同的字段。如何将其映射到模型?

示例Web服务响应

{
  "id": 0,
  "code": 0,
  "info": {
      "type": "ObjectA",
      "objId": 1,
      "data": [
         {
            "refId": 1,
            "description": "Object A1"
         },
         {
            "refId": 2,
            "description": "Object A2"
         }
     ] 
  }
}


{
  "id": 0,
  "code": 0,
  "info": {
      "type": "ObjectB",
      "amount": 10,
      "value": 20
  }
}

{
  "id": 0,
  "code": 0,
  "info": {
      "type": "ObjectC",
      "name": 10,
      "platform": "Android"
  }
}

主要结果模型类

public class Result {
   private int id;
   private int code;
   private AbstractObject info;
}

抽象类

public abstract class AbstractObject {
    private String type;
}

ObjectA类

public class ObjectA extends AbstractObject {
   private int objId;
   private List<ObjectAInfo> data;

   class ObjectAInfo {
      private int refId;
      private String description;
   }
}

ObjectB类

public class ObjectB extends AbstractObject {
   private int amount;
   private int value;
}

ObjectC类

public class ObjectC extends AbstractObject {
   private int name;
   private String platform;
}

我需要将 AbstractObject 的相应具体类映射到基于&#34;类型&#34;的值的Result类。

更新: 我的解决方案是扩展JsonDeserializer并将其注册为Gson实例中的类型适配器。

AbstractObject反序列化器类

public class AbstractObjectDeserializer implements JsonDeserializer<AbstractObject> {

@Override
public AbstractObject deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context)
        throws JsonParseException {
    JsonObject entry = jsonElement.getAsJsonObject();
    switch(entry.get("type").getAsString()) {
        case "ObjectA":
            return context.deserialize(jsonElement, ObjectA.class);
        case "ObjectB":
            return context.deserialize(jsonElement, ObjectB.class);
        case "ObjectC":
            return context.deserialize(jsonElement, ObjectC.class);
        default:
            throw new IllegalArgumentException("Can't deserialize " + jsonElement);
    }
  }
}

在gson实例中注册类

gson = new GsonBuilder().registerTypeAdapter(AbstractObject.class, new AbstractObjetcDeserializer()).create();

但它无法获得子类的正确信息。

{
  "id": 0,
  "code": 0,
  "info": {
     "type": "ObjectA"

     //Missing all other fields, only get the type from base class
  }
}

0 个答案:

没有答案