Gson反序列化 子类、接口实现类

起源于SpringSecurity的权限GrantedAuthority无法反序列化,fastjson反序列化出来的结果直接为空,使用gson报错为:

Interfaces can't be instantiated! Register an InstanceCreator or a TypeAdapter for this type.

原因:json反序列化的接收对象为一个父对象/接口类型时,无法确定实际类型。模型如下

新建一个接口/父类
Gson反序列化 子类、接口实现类_第1张图片
随便写两个实现类
Gson反序列化 子类、接口实现类_第2张图片
Gson反序列化 子类、接口实现类_第3张图片
需要序列化反序列化的类
Gson反序列化 子类、接口实现类_第4张图片
测试,因为实际类型无法确认,则无法反序列化Gson反序列化 子类、接口实现类_第5张图片
解决思路:需要保存对象的原始类型,反序列化时装配实现类对象
我此处新增了一个变量用来保存类名,实际使用其他编号id也可代替
Gson反序列化 子类、接口实现类_第6张图片
Gson反序列化 子类、接口实现类_第7张图片
自定义一个反序列化配置,用来识别父类下的各个子类,反序列化时装配其原始类型

public class FatherDeserializer implements JsonDeserializer<Father> {

    private Gson gson = new Gson();

    private Map<String, Class<? extends Father>> sonsType = new HashMap<>(16);

    public FatherDeserializer() {
        sonsType.put("Son1", Son1.class);
        sonsType.put("Son2", Son2.class);
    }

    @Override
    public Father deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject();
        Class<? extends Father> clazz = this.sonsType.get(jsonObject.get("className").getAsString());
        return gson.fromJson(json, clazz);
    }
}

构建Gson对象时传入自定义的反序列化配置,Father类型使用自定义的FatherDeserializer

        Gson gson = new GsonBuilder()
                .serializeNulls()
                .registerTypeAdapter(Father.class, new FatherDeserializer())
                .create();

测试使用Gson反序列化 子类、接口实现类_第8张图片

你可能感兴趣的:(java,json)