我正在尝试在Gson中为一个对象创建一个自定义反序列化器,该对象实际上只是一堆具有类型标识符的不同类型的包装器。
以下是我的问题域的简要概述:
我让用户向对方发送可能包含各种不相关的域对象的消息,我想将其反序列化为:
public class Message {
public String messageType;
public Object messageData;
}
messageData对象是通过JavaScript构建的,程序员决定将每个对象类型都塞进一个字段“messageData”。 messageData可以是任意数量的域对象,例如:User,Video,Website,Picture,它们不共享基类或接口。
所以(简化的)json对象看起来像:
{ "messageType": "video", "messageData": { "videoId": 1, "videoTitle": "my vid" } }
或
{ "messageType": "picture", "messageData": { "pictureId": 1, "pictureUrl": "http://www.example.com/cat.jpg" } }
目标是获取messageType并使用它来选择一个适当的类来反序列化它。
我想出了类似的东西:
public class MessageJsonDeserializer implements JsonDeserializer<Message> {
@Override
public Message deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject obj = json.getAsJsonObject();
Message message = new Message();
message.messageType = obj.get("messageType").getAsString();
message.messageData = MessageDataMapper.map(message.messageType, obj.get("messageData")); // maps and casts to the correct Video/Picture,Website etc..
return message;
}
}
这似乎工作正常,但是让我们说Message有很多其他字段可以自动序列化,然后我必须手动解析JsonObject并提取这些字段。
有没有办法让我可以使用混合方法让Gson自动序列化非对象字段,但是对于那个也考虑了messageType的messageData字段使用自定义序列化器?
答案 0 :(得分:2)
可能有点晚了,但关于RuntimeTypeAdapter的这个答案可能会帮助你解决这个问题:
https://stackoverflow.com/a/15737704/433421
RuntimeTypeAdapter使您能够在JSON中评估自配置的type-attribute,在您的情况下为“messageType”,并使用提供的POJO类注册其值。
查看此答案中提供的链接,以查看javadoc中的用法示例。
根据我的理解,GSon会处理这些POJO类本身的序列化和反序列化。
如果messageData中的那些字段包含任意对象,则必须像使用MessageJsonDeserializer一样注册自定义JsonDeserializer实例。
希望这有帮助。
答案 1 :(得分:1)
可悲的是,没有。至少不是我能够确定的。没有办法让它做“自定义反序列化字段X,但super.deserialize()其余部分”。天知道我试过了。如果这是任何安慰,那对我看过的每一个Json反序列化器来说都是如此。