Deserializing JSON to derived class of abstract class (给外国兄弟留个门,嘿嘿~)
抽象类
//抽象类 public abstract class Product { String type; } //派生类Phone public class Phone extends Product { //type = "phone" String brand; Integer price; } //派生类Drink public class Drink extends Product { //type = "drink" String color; Integer weight; String taste; }
现有一条json数据
{"products":[{"type":"phone", "brand":"xiaomi", "price":1999},{"type":"drink","weight":500,"taste":"orange"}]}
需要反序列化到
public class Data{ List<Product> products; }
Gson直接转会报错,因为反序列化的时候,抽象类Product不能被实例化,如果不是抽象类,可以反序列化成功,但仅有type属性,派生类其它属性会丢失
Data data = new Gson().fromJson(json, Data.class);
咋办?敲黑板!!!
String json = "{\"products\":[{\"type\":\"phone\", \"brand\":\"xiaomi\", \"price\":1999},{\"type\":\"drink\",\"weight\":500,\"taste\":\"orange\"}]}"; Gson gson = new GsonBuilder().registerTypeAdapter(Product.class, new JsonDeserializer<Product>() { @Override public Product deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject object = json.getAsJsonObject(); String type = object.get("type").getAsString(); if ("phone".equals(type)) { return context.deserialize(json, Phone.class); } else if ("drink".equals(type)) { return context.deserialize(json, Drink.class); } return null; } }).create(); Data data = gson.fromJson(json, Data.class);
运行效果
使用registerTypeAdapter 自定义一个适配器,遇到Product类型时,进来,我们先把type属性取出来,依据自己定义的派生类标识,使用各自类型反序列化,完美!网上大多使用TypeAdapter来自定义解析流程,太不灵活。
另外与 JsonDeserializer 相对应的还有 JsonSerializer,用法懒的试,应该也一样,各位需要自己尝试。
发表评论