使用Gson将json反序列化为抽象类的派生类

2022-03-25 13:52:49  阅读 587 次 评论 0 条

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);

运行效果

WX20220325-141406@2x.png

使用registerTypeAdapter 自定义一个适配器,遇到Product类型时,进来,我们先把type属性取出来,依据自己定义的派生类标识,使用各自类型反序列化,完美!网上大多使用TypeAdapter来自定义解析流程,太不灵活。

另外与 JsonDeserializer 相对应的还有 JsonSerializer,用法懒的试,应该也一样,各位需要自己尝试。

本文地址:http://www.bloguan.com/?id=583
版权声明:本文为原创文章,版权归 博观网 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?