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

时间:2014-10-11 00:17:26

标签: json gson abstract-class

我想序列化/反序列化使用gson扩展抽象对象的Object数组。为此,我创建了一个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!

如果我使BaseModel不是抽象的,它可以完美地工作,我想我可以为了这个工作而做。但我宁愿保留BaseModel应该是抽象的。抛出的异常表示它无法调用之前从未出现问题的no-args构造函数。将no-args构造函数添加到我的BaseModel类并不能解决问题,它仍然会显示相同的消息。无论如何我可以在保持BaseModel抽象的同时使其工作吗?

0 个答案:

没有答案