gson.toGson() 不调用自定义序列化方法

gson.toGson() doesn't invoke custom serialize method

我有一个抽象的 class 和一组具体的 classes.

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

}

//测试块

Gson gson =  new GsonBuilder().registerTypeAdapter(AbstractClass.class, new AbstractClassAdaptor()).create();

AbstractClass obj = new ConcreteClass();
String jsonString = gson.toJson(obj);

未调用 AbstractClassAdaptor 中的 Serialize 方法。这从 json 输出中可以明显看出,它在序列化后不包含任何类型和属性的痕迹。

实现此功能的一种方法(也是我迄今为止使用的唯一方法)是将所需类型传递给 toJson 方法。所以

String jsonString = gson.toJson(obj, AbstractClass.class);

将在 AbstractClassAdaptor 中调用您自定义的序列化程序。同样,反序列化时也需要这样做。

作为 GsonBuilder().registerTypeAdapter() 的文档

This registers the type specified and no other types: you must manually register related types! For example, applications registering boolean.class should also register Boolean.class.

所以您应该使用构建器模式来添加 AbstractClass 的所有实现 class 以使其工作。

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