GWT的序列化程序java.io.Serializable
支持有限,但出于安全考虑,它支持的类型为白名单.我找到的文档,例如此FAQ条目表示您要序列化的任何类型"必须包含在序列化策略白名单中",并且列表是在编译时生成的,但不解释编译器如何决定什么在白名单上.
生成的列表包含许多属于标准库的类型,例如java.lang.String
和java.util.HashMap
.尝试序列化时出现错误java.sql.Date
,该错误实现了Serializable
接口,但不在白名单中.如何将此类型添加到列表中?
有一种解决方法:Dummy
使用您希望包含在序列化中的所有类型的成员字段定义一个新类.然后在RPC接口中添加一个方法:
Dummy dummy(Dummy d);
实现就是这样:
Dummy dummy(Dummy d) { return d; }
而async接口将具有:
void dummy(Dummy d, AsyncCallback< Dummy> callback);
GWT编译器会选择它,因为Dummy
类引用了这些类型,它会将它们包含在白名单中.
示例Dummy
类:
public class Dummy implements IsSerializable { private java.sql.Date d; }
您在服务界面中包含的任何特定类型以及它们引用的任何类型都将自动列入白名单,只要它们实现java.io.Serializable,例如:
public String getStringForDates(ArrayListdates);
将导致ArrayList和Date都包含在白名单中.
如果您尝试使用java.lang.Object而不是特定类型,则会变得更加棘手:
public Object getObjectForString(String str);
因为编译器不知道白名单是什么.在这种情况下,如果对象未在服务接口中的任何位置引用,则必须使用IsSerializable接口显式标记它们,否则它将不允许您通过RPC机制传递它们.
白名单由GWT编译器生成,包含IsSerializable标记接口指定的所有条目.
要向列表中添加类型,您只需确保该类实现IsSerializable接口.
此外,为了使序列化正常工作,类必须具有默认的无arg构造函数(如果需要,构造函数可以是私有的).此外,如果类是内部,则必须将其标记为静态.