GWT:对序列化错误感到困惑
我正在使用 GWT 2.4。我遇到序列化问题。我的服务有一个方法...
@RemoteServiceRelativePath("retrieveChild")
public interface ChildRetrievalService extends RemoteService {
...
Collection<Node> getRootNodes();
其中我的“Node”类定义如下...
public class Node implements Serializable {
private Long id;
private Node parent;
private String info;
private List<Node> children;
public Node() {
this.children = new ArrayList<Node>();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
} // setId
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
} // setInfo
public List<Node> getChildren() {
return children;
}
public boolean equals(Object node) {
return node != null &&
node instanceof Node &&
((Node) node).getId() == id;
}
public int hashCode() {
return getId().hashCode();
}
}
但是在尝试调用服务方法时出现错误,抱怨序列化。 HashMap 和 Node 都是可序列化的,那么问题出在哪里呢?
[WARN] Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException:类型“java.util.HashMap$Values”未包含在此 SerializationPolicy 可以序列化的类型集中,或者无法加载其 Class 对象。出于安全目的,此类型不会被序列化。: instance = [com.cme.draganddroptree.shared.Node@0, com.cme.draganddroptree.shared.Node@1, com.cme.draganddroptree.shared.Node@2 ,com.cme.draganddroptree.shared.Node@3,com.cme.draganddroptree.shared.Node@4] 在 com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619) 在 com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126) 在 com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:153) 在 com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:539) 在 com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:616) 在 com.google.gwt.user.server.rpc.RPC.encodeResponseForSuccess(RPC.java:474) 在 com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:571) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248) 在 com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 在 org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) 在 org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362) 在 org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 在 org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) 在 org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729) 在 org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 在 org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 在 org.mortbay.jetty.Server.handle(Server.java:324) 在 org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505) 在 org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843) 在 org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647) 在 org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205) 在 org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380) 在 org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395) 在 org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
谢谢,-戴夫
I'm using GWT 2.4. I'm having a serialization issue. My service has a method ...
@RemoteServiceRelativePath("retrieveChild")
public interface ChildRetrievalService extends RemoteService {
...
Collection<Node> getRootNodes();
In which my "Node" class is defined as follows ...
public class Node implements Serializable {
private Long id;
private Node parent;
private String info;
private List<Node> children;
public Node() {
this.children = new ArrayList<Node>();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
} // setId
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
} // setInfo
public List<Node> getChildren() {
return children;
}
public boolean equals(Object node) {
return node != null &&
node instanceof Node &&
((Node) node).getId() == id;
}
public int hashCode() {
return getId().hashCode();
}
}
But I'm getting an error when trying to invoke the service method, complaining about serialization. Both HashMap and Node are Serializable, so where is everything breaking down?
[WARN] Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type 'java.util.HashMap$Values' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = [com.cme.draganddroptree.shared.Node@0, com.cme.draganddroptree.shared.Node@1, com.cme.draganddroptree.shared.Node@2, com.cme.draganddroptree.shared.Node@3, com.cme.draganddroptree.shared.Node@4]
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:153)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:539)
at com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:616)
at com.google.gwt.user.server.rpc.RPC.encodeResponseForSuccess(RPC.java:474)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:571)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Thanks, - Dave
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不能将抽象类型(或接口)用于 GWT RPC 的方法参数:
有关详细信息,请参阅此处。
归根结底,RPC 机制无法序列化您的参数,因为它不知道它到底是什么。或者,任何序列化任何可能的具体实现的方法都是不切实际的。因此,您必须选择最适合您需求的具体课程。
You can't use an abstract type (or interface) for a method parameter for a GWT RPC:
See here for details.
It boils down to the fact that the RPC mechanism can't serialize what your parameter because it doesn't know what it's really going to be. Alternatively, any approach to serialize any possible concrete implementation is just not practical. So you have to pick a concrete class the best suits your needs.
始终对 RPC 中使用的数据使用具体类型。因为 GWT 编译器需要生成所有子类的实现,因为它不知道将从服务器发送什么子类型。这可能意味着对于某些类型或接口,它可能会导致大量的开销,添加大量从未使用过的类型。例如,当您指定了 List 时,您知道您只使用 ArrayList。
这也可能会导致此错误,因为它想要添加一个无法序列化的子类型。
Always use a concrete type for data used in RPC. Because the GWT compiler needs to generate implementations for all subclasses, as it doesn't know what sub type will be send from the server. This can mean for some types or interfaces it can lead to a lot over overhead, lots of types added, which are never used. For example you know you only use ArrayList, when you have a List specified.
This probably also can cause this error, because it wants to add a substype it can't serialize.