我希望有一个自定义的 GSON 反序列化器,这样每当它反序列化一个 JSON 对象(即大括号 { ... }
内的任何内容)时,它都会寻找一个 $type
节点并使用其针对该类型的内置反序列化功能进行反序列化。如果未找到 $type
对象,它就会执行正常操作。
例如,我希望它能工作:
{
"$type": "my.package.CustomMessage"
"payload" : {
"$type": "my.package.PayloadMessage",
"key": "value"
}
}
public class CustomMessage {
public Object payload;
}
public class PayloadMessage implements Payload {
public String key;
}
调用:Object customMessage = gson.fromJson(jsonString, Object.class)
。
所以目前如果我将 payload
类型更改为 Payload
接口(interface):
public class CustomMessage {
public Payload payload;
}
然后下面的 TypeAdapaterFactory
将执行我想要的操作:
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
final PojoTypeAdapter thisAdapter = this;
public T read(JsonReader reader) throws IOException {
JsonElement jsonElement = (JsonElement)elementAdapter.read(reader);
if (!jsonElement.isJsonObject()) {
return delegate.fromJsonTree(jsonElement);
}
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonElement typeElement = jsonObject.get("$type");
if (typeElement == null) {
return delegate.fromJsonTree(jsonElement);
}
try {
return (T) gson.getDelegateAdapter(
thisAdapter,
TypeToken.get(Class.forName(typeElement.getAsString()))).fromJsonTree(jsonElement);
} catch (ClassNotFoundException ex) {
throw new IOException(ex.getMessage());
}
}
但是,我希望它在 payload
是 Object
类型或与此相关的任何类型时工作,如果不能,则抛出某种类型匹配异常' t 分配变量。
最佳答案
查看 Gson 的源代码,我发现了我认为的问题所在:
// built-in type adapters that cannot be overridden
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.FACTORY);
// user's type adapters
factories.addAll(typeAdapterFactories);
如您所见,ObjectTypeAdapter
将优先于我的工厂。
据我所知,唯一的解决方案是使用反射从列表中删除 ObjectTypeAdapter
或在它之前插入我的工厂。我已经这样做了,而且很有效。
关于java - Gson自定义序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23695649/