2010-06-17 49 views
13

我有以下方法的RPC服务:gwt - 在RPC调用中使用List <Serializable>?

public List<Serializable> myMethod(TransactionCall call) {...} 

,但我得到时,分析了该方法的警告,然后将RPC调用失败

Analyzing 'my.project.package.myService' for serializable types 
Analyzing methods: 
public abstract java.util.List<java.io.Serializable> myMethod(my.project.package.TransactionCall call) 
Return type: java.util.List<java.io.Serializable> 
[...] 
java.io.Serializable 
Verifying instantiability 
(!) Checking all subtypes of Object wich qualify for serialization 

看来我不能使用Serializable为我的列表...我可以使用我自己的接口,而不是(像AsyncDataInterface,这实现了Serializ但实际上我的方法会返回一个列表自定义对象和基本对象(如Strings,int ....)。

所以我的问题是:

  • 它是一个非标准的行为呢? (我不明白为什么我不能在这种情况下使用此接口)
  • 有没有人有这种情况的解决方法?

回答

27

当在RPC调用中传递对象时,在RPC接口中声明具体的参数类型是一种很好的做法。如果由于某种原因,您不能在RPC界面中使用具体类,尽可能使其具体。

这是因为GWT编译器在发射javascript时必须考虑编译单元中List的所有可能变体。这包括在类路径中扩展List和Serializable接口的所有类。排列可能很大,这会影响您的编译时间以及应用程序下载大小。

所以最好的方法是定义你的界面

public ArrayList<YourType> myMethod(TransactionCall call) {...} 

而不是

public List<Serializable> myMethod(TransactionCall call) {...} 

这样编译器来生成唯一的ArrayList和YourType扩展编译单元。好处是编译速度更快,编译的JavaScript文件更小,因此可以更快地下载应用程序。

如果您必须在RPC调用中返回大量不相关的对象,请尝试创建包装类并返回包装类的返回对象。在RPC方法定义中使用包装类。抵制将包装字段声明为Object或Serializable的冲动,您将否定使用包​​装器获得的所有序列化好处。相反,您可以为每个想要通过RPC调用返回的具体类型定义一个Wrapper接口和一小部分Wrapper实现。

1

您可能想要检查序列化策略文件是否不是问题的根源。

Quote from GWT documentation

然而,有一个条件,以便能够在新的GWT的RPC系统的java.io.Serializable支持。

RPC现在在GWT编译期间生成序列化策略文件。序列化策略文件包含可以序列化的允许类型的白名单。它的名字是一个强大的散列名称,后跟.gwt.rpc。为了支持java.io.Serializable,应用程序将通过线路发送的类型必须包含在序列化策略白名单中。此外,序列化策略文件必须作为公共资源部署到您的Web服务器,可以通过ServletContext.getResource()从RemoteServiceServlet访问。如果没有正确部署,RPC将以1.3.3兼容模式运行,并拒绝序列化实现java.io.Serializable的类型。

0

我没有看到定义列表< Serializable>作为返回值的要点。 Serializable类型在服务API声明中不提供附加信息。无论如何,GWT将在运行时进行序列化检查。

在你的情况下,列表元素除了Object之外没有共同的祖先,我会使用List <?>。