如何从GWT的序列化策略中删除实现类型?

时间:2010-01-22 20:04:34

标签: java gwt interface

与此问题相反:How do I add a type to GWT's Serialization Policy whitelist?

GWT正在将不受欢迎的类型添加到序列化策略中并使我的JS膨胀。如何手动修剪GWT白名单?或者我应该呢?

例如,如果我将接口List放在GWT RPC服务类上,GWT必须生成处理ArrayList,LinkedList,Stack,Vector等的Javascript,即使我的团队知道我们只会返回一个ArrayList。我可以让方法的返回类型为ArrayList,但我喜欢依赖于接口而不是特定的实现。毕竟,也许有一天我们会将其切换并返回,例如一个LinkedList。在这种情况下,我想强制GWT序列化策略仅针对ArrayList和LinkedList进行编译。没有堆栈或向量。

这些隐含的限制有一个我能想到的巨大缺点:团队的新成员开始返回Vector,这将是一个运行时错误。所以除了标题中的问题之外,你围绕这个设计的经验是什么?

2 个答案:

答案 0 :(得分:8)

有一个属性可以将此类列入黑名单。例如,要将非ArrayList集合列入黑名单,请将这些行添加到* .gwt.xml:

<extend-configuration-property name="rpc.blacklist" value="java.util.HashSet"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.LinkedHashSet"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.LinkedList"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.Stack"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.TreeMap"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.TreeSet"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.Vector"/>

当我通过网络发送GWT的内置com.google.gwt.user.client.ui.SuggestOracle$Response对象时,这对于减少JS大小是必要的。这样的对象包含一个java.util.Collection,但我知道我只会发回一个ArrayList。

我仍然尊重编译时检查的优点,正如其他回复,评论和我原来的问题所讨论的那样。实际上,如果GWT开始采用序列化的其他实现(为什么这不是白名单?),这是一个片状解决方案。然而,这个“rpc.blacklist”属性使我免于滚动自己的SuggestOracle只是为了获得更具体的集合类型。

答案 1 :(得分:6)

虽然没有好的框架应该尝试更改其用户,但让我尝试解释为什么GWT序列化的工作方式。我不知道这个的确切机制,所以我可能是错的,但这是我所看到的要点。

GWT已经删除了RPC接口之外的额外代码 - 例如,如果您使用不带RPC的应用程序,您可以自由使用List和Map等接口并设置为您的内容 - GWT将自动仅包含实现你实际使用的。为什么?因为它可以访问您的代码,并且能够实际遍历代码的所有可见排列并修剪未使用的类。因此,当使用接口时,GWT实际上不会创建类爆炸。

问题完全是RPC。 RPC服务的要点是服务器需要实现RPC接口 - 这意味着如果接口指示方法需要返回列表,那么服务器可以自由地返回它想要的列表的任何实现,只要因为它可以序列化。

这就是问题 - GWT绝对无法知道服务器将在编译时或将来的某个时刻使用什么接口。服务器代码可以并且在许多情况下将独立于客户端代码进行开发。因此,通过线路安全地接收List类型对象的唯一方法是事先了解它的每个可能的实现。