反序列化具有未知编译时类型的泛型,其中字段指示类型

发布于 2024-10-26 23:27:33 字数 1479 浏览 0 评论 0原文

这可行,但很糟糕 - 有更好的方法吗?

我有一个通用类,在这个简单的示例中如下

public class MsgWrapper<T> {
@Expose
private T Message;
@Expose
private String Type;
private String uri;
}

序列化很讨厌但微不足道,例如

Type typeToken = new TypeToken<MsgWrapper<Notice>>(){}.getType();
gson.toJson(message,typeToken);

服务器接收 json,它可以

MsgWrapper<Notice> or MsgWrapper<Alert>

是通知,然后“类型”字段将显示“通知” 如果它是一个警报,那么“类型”字段会显示“警报”。

目前我已经实现了一个自定义反序列化器,

        public MsgWrapper deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject object = json.getAsJsonObject();
        if(object.has("Type"))
        {
            MsgWrapper msgWrapper=new MsgWrapper();
            msgWrapper.setType(object.get("Type").getAsString());
            if(msgWrapper.getType().equalsIgnoreCase("Notice"))
            {
             msgWrapper.setMessage(context.deserialize(object.get("Message"), Notice.class));
            }
            else if(msgWrapper.getType().equalsIgnoreCase("Alert"))
            {
             msgWrapper.setMessage(context.deserialize(object.get("Message"), Alert.class));   
            }
            return msgWrapper;
        }
        else
        {
            throw new JsonParseException("something is wrong...");
        }
    }
}

这感觉非常笨拙和错误。有更好的办法吗?

This works but it is horrible - is there a better way?

I have a generic class which in this simple example is as follows

public class MsgWrapper<T> {
@Expose
private T Message;
@Expose
private String Type;
private String uri;
}

Serialising is nasty but trivial e.g.

Type typeToken = new TypeToken<MsgWrapper<Notice>>(){}.getType();
gson.toJson(message,typeToken);

The server receives json which can be either

MsgWrapper<Notice> or MsgWrapper<Alert>

If it is a notice then the 'Type' field will say 'notice'
If it is an alert then the 'Type' field will say 'alert'

At the moment I've implemented a custom deserialiser

        public MsgWrapper deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject object = json.getAsJsonObject();
        if(object.has("Type"))
        {
            MsgWrapper msgWrapper=new MsgWrapper();
            msgWrapper.setType(object.get("Type").getAsString());
            if(msgWrapper.getType().equalsIgnoreCase("Notice"))
            {
             msgWrapper.setMessage(context.deserialize(object.get("Message"), Notice.class));
            }
            else if(msgWrapper.getType().equalsIgnoreCase("Alert"))
            {
             msgWrapper.setMessage(context.deserialize(object.get("Message"), Alert.class));   
            }
            return msgWrapper;
        }
        else
        {
            throw new JsonParseException("something is wrong...");
        }
    }
}

This feels deeply clunky and wrong. Is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

世界和平 2024-11-02 23:27:33

就当前 Gson 版本的多态反序列化而言,您发布的解决方案或多或少是一样好的。

您可以实现一些小的更改,以使自定义解串器在外部可配置,按照 Dan 建议的方式,并提到更改为使用 Map

看起来 Gson 很快就会有 RuntimeTypeAdapter 可用于更简单的多态反序列化,而不是使用自定义反序列化器。请参阅 http://code.google.com/p/google- gson/issues/detail?id=231 了解更多信息。即使您无法使用 RuntimeTypeAdapter,它至少提供了一个创建可配置自定义反序列化器的示例。

如果您可以切换 JSON 映射 API,那么我建议考虑 Jackson,因为它有一个可用且相对简单的多态反序列化器机制。我在 http://programmerbruce.blogspot 发布了一些简单的示例.com/2011/05/deserialize-json-with-jackson-into.html

The solution you posted is more-or-less as good as it gets as far as polymorphic deserialization with the current Gson release is concerned.

You could implement some small changes to make the custom deserializer externally configurable, along the lines as Dan suggested with the mention of changing to use Map<String, Deserializer>.

Instead of using a custom deserializer, it looks like Gson will soon have the RuntimeTypeAdapter available for simpler polymorphic deserialization. See http://code.google.com/p/google-gson/issues/detail?id=231 for more info. Even if you cannot use the RuntimeTypeAdapter, it at least provides an example for creating a configurable custom deserializer.

If you can switch JSON mapping APIs, then I recommend considering Jackson, as it has a working and relatively simple polymorphic deserializer mechanism available. I posted some simple examples at http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文