gwt - 在 RPC 调用中使用 List<Serializable>?

2022-09-03 18:11:02

我有一个具有以下方法的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

似乎我不能为我的列表使用序列化...我可以改用我自己的接口(类似于AsyncDataInterface,它实现了可序列化接口),但事实是,我的方法将返回一个列表自定义对象和基本对象(如Strings,int....)。

所以我的问题是:

  • 这是一种标准行为吗?(在这种情况下,我不知道为什么我不能使用此界面)
  • 有没有人有解决这种情况的解决方法?

答案 1

在 RPC 调用中传递对象时,最好在 RPC 接口中声明具体的参数类型。如果由于某种原因无法在 RPC 接口中使用具体类,请尝试尽可能具体。

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

因此,最好的方法是将接口定义为

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

而不是

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

这样,编译器必须仅为 ArrayList 和 YourType 扩展生成编译单元。这样做的好处是编译时间更快,编译的javascript文件更小,因此可以更快地下载应用程序。

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


答案 2

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

引用GWT文档

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

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