【问题标题】:GWT: Baffled by serialization errorGWT:被序列化错误迷惑
【发布时间】:2011-12-03 01:35:40
【问题描述】:

我正在使用 GWT 2.4。我有一个序列化问题。我的服务有一个方法...

@RemoteServiceRelativePath("retrieveChild")
public interface ChildRetrievalService extends RemoteService {
    ...
    Collection<Node> getRootNodes();   

其中我的“节点”类定义如下...

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) 在 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)

谢谢,- 戴夫

【问题讨论】:

  • 我会尝试将 Collection 的具体类型放在 RemoteService 接口中。有时 GWT 可能会对是否将其列入白名单感到奇怪。

标签: java gwt serialization


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    目前的 GWT RPC 系统是基于 具体类型。在一般情况下,相同的混凝土类型必须 在客户端和服务器上都可用。虽然习惯 序列化器可用于更改任何一个中使用的实际类型 客户端或服务器,序列化类型必须知道 要使用的序列化程序。当 RPC 接口是 使用任意数量的(抽象)类型声明 服务器上的实现。

    详情请见here

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多