GWT:因序列化错误而感到困惑

时间:2011-10-07 14:19:46

标签: java gwt serialization

我正在使用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都是Serializable,所以一切都崩溃了吗?

[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)     at 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)     at 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)     at 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)

谢谢, - 戴夫

2 个答案:

答案 0 :(得分:2)

您不能将抽象类型(或接口)用于GWT RPC的方法参数:

  

当前的GWT RPC系统基于序列化   具体类型。在一般情况下,必须使用相同的混凝土类型   在客户端和服务器上都可用。一个习惯   Serializer可用于更改任何一个中使用的实际类型   客户端或服务器,序列化类型必须具备   串行器使用。这是RPC接口时的问题   声明使用(抽象)类型,其中有任意多个   在服务器上实现。

有关详细信息,请参阅here

归结为RPC机制无法序列化您的参数,因为它不知道它究竟是什么。或者,任何序列化任何可能的具体实现的方法都是不切实际的。因此,您必须选择最适合您需求的具体课程。

答案 1 :(得分:1)

始终对RPC中使用的数据使用具体类型。因为GWT编译器需要为所有子类生成实现,因为它不知道将从服务器发送什么子类型。这可能意味着对于某些类型或接口,它可能导致大量开销,添加许多类型,从未使用过。例如,当您指定了List时,您知道只使用ArrayList。

这可能也会导致此错误,因为它想要添加一个无法序列化的子类型。