Gson定制序列化 [英] Gson custom serialization
问题描述
我希望有一个自定义的GSON反序列化器,以便每当它反序列化JSON对象(即大括号{ ... }
中的任何内容)时,它将查找$type
节点并使用其内置的反序列化功能对该类型进行反序列化.如果未找到$type
对象,则它会像平常一样执行操作.
I wish to have a custom GSON deserializer such that whenever it is deserializing a JSON object (i.e. anything within curly brackets { ... }
), it will look for a $type
node and deserialize using its inbuilt deserializing capability to that type. If no $type
object is found, it just does what it normal does.
因此,例如,我希望它可以工作:
So for example, I would want this to work:
{
"$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
界面:
So currently if I change the payload
type to the Payload
interface:
public class CustomMessage {
public Payload payload;
}
然后以下TypeAdapaterFactory
将执行我想要的操作:
Then the following TypeAdapaterFactory
will do what I want:
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
或与此相关的任何类型时起作用,并在无法分配变量的情况下抛出某种类型匹配异常.
However, I would like it to work when payload
is of type Object
or any type for that matter, and throw some sort of type match exception if it can't assign the variable.
推荐答案
看着Gson的源代码,我发现了问题所在
Looking at the source for Gson, I have found what I think is the issue:
// 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
将优先于我的工厂.
As you can see the ObjectTypeAdapter
will take precedence over my factory.
据我所知,唯一的解决方案是使用反射从列表中删除ObjectTypeAdapter
或在其前面插入我的工厂.我已经做到了,而且行得通.
The only solution as far as I can see is to use reflection to remove the ObjectTypeAdapter
from the list or insert my factory before it. I have done this and it works.
这篇关于Gson定制序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!