我有一个带有TreeMap的可序列化对象。
Map<String, Dogs> dogsByNames = Maps.newTreeMap(); // guava style
到目前为止,一切都很好。 现在忽略密钥的情况是必要的:
Map<String, Dogs> dogsByNames = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
这不起作用,因为String.CASE_INSENSITIVE_ORDER不是serialzable:
com.google.gwt.user.client.rpc.SerializationException:输入 'java.lang.String $ CaseInsensitiveComparator'未包括在内 可以通过此SerializationPolicy序列化的类型集 无法加载其Class对象。出于安全考虑,此类型 不会被序列化:instance = java.lang.String$CaseInsensitiveComparator@f26f68
所以我创建了自己的一个:
private static abstract class MyComparator<T>
implements
Comparator<T>, // extends Ordering<T> do not work
IsSerializable { // Serializable do not work
}
public static final MyComparator<String> CASE_INSENSITIVE_ORDER = new MyComparator<String>() {
@Override
public int compare(final String left, final String right) {
if (null == left) {
return (null == right) ? 0 : -1;
} else if (null == right) {
return 1;
}
return left.compareToIgnoreCase(right);
}
};
但这仍然无效。
怎么了?
解决方案:
protected static class MyOrdering // no-private!!!
extends
Ordering<String>
implements
IsSerializable {
@Override
public int compare(final String left, final String right) {
if (null == left) {
return (null == right) ? 0 : -1;
} else if (null == right) {
return 1;
}
return left.compareToIgnoreCase(right);
}
}
public static final Ordering<String> CASE_INSENSITIVE_ORDER = new MyOrdering();
答案 0 :(得分:5)
您创建的CASE_INSENSITIVE_ORDER是一个匿名类,无法在GWT中序列化。要使GWT可序列化,您需要
创建自定义顶级课程(例如
)CaseInsensitiveOrder implements Comparator<..>, Serializable {
...
}
像你一样创建一个常量CASE_INSENSITIVE_ORDER
。
CaseInsensitiveOrder_CustomFieldSerializer
)创建自定义字段序列化程序,该字段序列化程序返回CASE_INSENSITIVE_ORDER
上的deserialize()
实例。答案 1 :(得分:0)
错误的堆栈跟踪会有所帮助。但是我会冒这样的猜测,你会得到一个例外:
com.google.gwt.user.client.rpc.SerializationException:输入 'com.foo.Bar.MyComparator'未包括在可以的类型集中 由此SerializationPolicy序列化或其Class对象不能 加载。出于安全考虑,此类型不会被序列化
这是因为GWT在编译时创建了它可能需要序列化的所有类型的列表。这是“序列化政策”。为此,GWT检查所有RPC方法的参数和返回类型,并搜索所有“可到达”类型。
编译器可能没有意识到您的Comparator将被序列化,并且它没有被添加到序列化策略中。
解决方法是声明一个虚方法,该方法将所有可能需要序列化的类型作为参数,如this other SO answer中所述。类似的东西:
// in your RPC interface
SerializationWhitelist dummyMethodForSerializationPolicy(SerializationWhitelist serializationWhiteList);
// the SerializableWhiteList class
public class SerializationWhitelist {
public Bar.MyComparator<String> myComparator;
}