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

时间:2015-01-24 07:30:44

标签: java json serialization deserialization

我有一个抽象类和一组具体的类。

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输出中很明显,它在序列化后不包含类型和属性的痕迹。

2 个答案:

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