我有一个抽象类和一组具体的类。
class AbstractClass {
..
}
class ConcreteClass extends AbstractClass {
..
}
我有一个自定义适配器,它实现了JsonSerializer和JsonDeserializer
public class AbstractClassAdaptor implements JsonSerializer<AbstractClass>, JsonDeserializer<AbstractClass> {
@Override
public JsonElement serialize(AbstractClass src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.add("type", new JsonPrimitive(src.getClass().getSimpleName()));
result.add("properties", context.serialize(src, src.getClass()));
return result;
}
@Override
public AbstractClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String type = jsonObject.get("type").getAsString();
JsonElement element = jsonObject.get("properties");
try {
return context.deserialize(element, Class.forName("com.myjson." + type));
} catch (ClassNotFoundException cnfe) {
throw new JsonParseException("Unknown element type: " + type, cnfe);
}
}
// TestBlock
Gson gson = new GsonBuilder().registerTypeAdapter(AbstractClass.class, new AbstractClassAdaptor()).create();
AbstractClass obj = new ConcreteClass();
String jsonString = gson.toJson(obj);
未调用AbstractClassAdaptor中的Serialize方法。这在json输出中很明显,它在序列化后不包含类型和属性的痕迹。
答案 0 :(得分:1)
实现此功能的一种方法(也是我目前使用的唯一方法)是将所需类型传递给toJson
方法。所以
String jsonString = gson.toJson(obj, AbstractClass.class);
将在AbstractClassAdaptor
中调用您自定义的序列化程序。同样,在反序列化时你需要这样做。
答案 1 :(得分:0)
作为GsonBuilder()的文档.registerTypeAdapter()
这会注册指定的类型而不是其他类型:您必须手动注册相关类型!例如,注册boolean.class的应用程序也应该注册Boolean.class。
因此,您应该使用构建器模式添加AbstractClass类的所有实现以使其工作。
Set<Class<? extends AbstractClass>> classes = someComponentsScan (AbstractClass.class);
GsonBuilder builder = new GsonBuilder();
for(Class<? extends AbstarctClass> clazz : classes){
builder.registerTypeAdapter(clazz, new AbstractClassAdaptor());
}
Gson gson = builder.create();