14

我有一个使用以下方法的 RPC 服务:

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 which qualify for serialization

看来我不能将 Serializable 用于我的列表...我可以改用我自己的接口(类似于 AsyncDataInterface,它实现了 Serializable 接口)但事实是我的方法将返回一个列表自定义对象和基本对象(例如作为字符串,int....)。

所以我的问题是:

  • 这是标准行为吗?(我不明白为什么在那种情况下我不能使用这个界面)
  • 有没有人有解决这种情况的方法?
4

3 回答 3

29

当通过 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 实现。

于 2010-06-17T09:01:29.763 回答
1

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

引用 GWT 文档

但是,有一个条件可以在新的 GWT RPC 系统中启用对 java.io.Serializable 的支持。

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

于 2010-06-17T08:03:37.740 回答
0

我看不出将 List<Serializable> 定义为返回值的意义。Serializable 类型在服务 API 声明中不提供其他信息。无论如何,GWT 都会在运行时进行序列化检查。

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

于 2010-06-17T08:15:56.397 回答