这有效,但很糟糕 - 还有更好的方法吗?
我有一个泛型类,在这个简单的例子中如下
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...");
}
}
}
这让人感到非常笨拙和错误。还有更好的方法吗?
答案 0 :(得分:1)
就当前Gson版本的多态反序列化而言,您发布的解决方案或多或少都是好的。
您可以实施一些小的更改,使自定义反序列化程序可以在外部配置,就像Dan在提到更改使用Map<String, Deserializer>
时建议的那样。
而不是使用自定义反序列化器,看起来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发布了一些简单的例子。