GSON:基于包含对象中的String反序列化内部对象

时间:2013-08-26 21:12:58

标签: java gson

我正在尝试在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字段使用自定义序列化器?

2 个答案:

答案 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反序列化器来说都是如此。