GWT: сбит с толку ошибкой сериализации - PullRequest
1 голос
/ 07 октября 2011

Я использую 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)

Спасибо, - Дейв

Ответы [ 2 ]

2 голосов
/ 07 октября 2011

Нельзя использовать абстрактный тип (или интерфейс) для параметра метода для RPC GWT:

Текущая система RPC GWT основана на сериализации конкретных типов.В общем случае идентичный конкретный тип должен быть доступен как на клиенте, так и на сервере.В то время как пользовательский сериализатор может использоваться для изменения фактического типа, используемого на клиенте или сервере, сериализованный тип должен обладать знаниями об используемом сериализаторе.Это проблематично, когда интерфейсы RPC объявляются с использованием (абстрактных) типов, которых на сервере произвольно много реализаций.

Подробнее см. здесь .

Это сводится к тому, что механизм RPC не может сериализовать, что ваш параметр, потому что он не знает, что это будет на самом деле.В качестве альтернативы, любой подход к сериализации любой возможной конкретной реализации просто не практичен.Таким образом, вы должны выбрать конкретный класс, который наилучшим образом соответствует вашим потребностям.

1 голос
/ 07 октября 2011

Всегда используйте конкретный тип для данных, используемых в RPC.Поскольку компилятор GWT должен генерировать реализации для всех подклассов, поскольку он не знает, какой подтип будет отправляться с сервера.Это может означать, что для некоторых типов или интерфейсов это может привести к большим накладным расходам, множеству добавленных типов, которые никогда не используются.Например, вы знаете, что используете ArrayList, только когда у вас указан список.

Это, вероятно, также может вызвать эту ошибку, поскольку он хочет добавить подтип, который не может сериализовать.

...