Json 在GSON中反序列化扩展抽象类的类型

Json 在GSON中反序列化扩展抽象类的类型,json,gson,abstract-class,Json,Gson,Abstract Class,我想序列化/反序列化使用gson扩展抽象对象的对象数组。为此,我制作了一个TypeHierarchyAdapter,如下所示: private static class BaseModelAdapter<T extends BaseModel> implements JsonSerializer<T>, JsonDeserializer<T>{ private static final String MODEL_TYPE_PROPERTY =

我想序列化/反序列化使用gson扩展抽象对象的对象数组。为此,我制作了一个TypeHierarchyAdapter,如下所示:

    private static class BaseModelAdapter<T extends BaseModel> implements JsonSerializer<T>, JsonDeserializer<T>{

    private static final String MODEL_TYPE_PROPERTY = "MODEL_TYPE_PROPERTY";
    private static final String CHILDREN_PROPERTY = "children";
    private static final Gson gson = new Gson();

    @Override
    public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if(!json.getAsJsonObject().has(MODEL_TYPE_PROPERTY)) {
            throw new JsonParseException("Couldn't find target class! \n" + json.toString());
        }
        final String className = json.getAsJsonObject().get(MODEL_TYPE_PROPERTY).getAsString();
        try {
            return (T) gson.fromJson(json, Class.forName(className));
        } catch (ClassNotFoundException e) {
            Log.e(TAG, e);
            throw new JsonParseException("Couldn't find target class!", e);
        }
    }

    @Override
    public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
        final JsonObject ret = gson.toJsonTree(src).getAsJsonObject();
        ret.add(CHILDREN_PROPERTY, context.serialize(src.getChildren()));
        ret.addProperty(MODEL_TYPE_PROPERTY, src.getClass().getName());
        return ret;
    }

}
TypeToken<List<BaseModel>> typeToken = new TypeToken<List<BaseModel>>(){};
GsonBuilder builder = new GsonBuilder();
builder.registerTypeHierarchyAdapter(BaseModel.class, new BaseModelAdapter<BaseModel>());
builder.setPrettyPrinting();
Gson special = builder.create();
String json = special.toJson(featured); //Works!
List<BaseModel> baseModels = special.fromJson(json, typeToken.getType()); //Exception Thrown!
我使用的适配器如下所示:

    private static class BaseModelAdapter<T extends BaseModel> implements JsonSerializer<T>, JsonDeserializer<T>{

    private static final String MODEL_TYPE_PROPERTY = "MODEL_TYPE_PROPERTY";
    private static final String CHILDREN_PROPERTY = "children";
    private static final Gson gson = new Gson();

    @Override
    public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if(!json.getAsJsonObject().has(MODEL_TYPE_PROPERTY)) {
            throw new JsonParseException("Couldn't find target class! \n" + json.toString());
        }
        final String className = json.getAsJsonObject().get(MODEL_TYPE_PROPERTY).getAsString();
        try {
            return (T) gson.fromJson(json, Class.forName(className));
        } catch (ClassNotFoundException e) {
            Log.e(TAG, e);
            throw new JsonParseException("Couldn't find target class!", e);
        }
    }

    @Override
    public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
        final JsonObject ret = gson.toJsonTree(src).getAsJsonObject();
        ret.add(CHILDREN_PROPERTY, context.serialize(src.getChildren()));
        ret.addProperty(MODEL_TYPE_PROPERTY, src.getClass().getName());
        return ret;
    }

}
TypeToken<List<BaseModel>> typeToken = new TypeToken<List<BaseModel>>(){};
GsonBuilder builder = new GsonBuilder();
builder.registerTypeHierarchyAdapter(BaseModel.class, new BaseModelAdapter<BaseModel>());
builder.setPrettyPrinting();
Gson special = builder.create();
String json = special.toJson(featured); //Works!
List<BaseModel> baseModels = special.fromJson(json, typeToken.getType()); //Exception Thrown!

如果我使BaseModel不是抽象的,那么它就可以完美地工作,我想为了使它工作,我可以这样做。但我更愿意保持BaseModel的抽象性。抛出的异常表示它无法调用no-args构造函数,而gson以前从未遇到过这个问题。向我的BaseModel类添加一个无参数构造函数并不能解决这个问题,它仍然会显示相同的消息。在保持BaseModel抽象的同时,是否还有其他方法可以让它工作?

建议使用TypeAdapters。新的应用程序应该更喜欢TypeAdapter,它的流API比这个接口的树API更有效。你最好试试TypeAdapters,我从来没有用过JsonSerializer和JsonDeserializer。也许这就是你的解决办法。