GWT:响应无法反序列化

问题描述 投票:6回答:8

我正在使用GWT(2.4)与Spring集成,就像在这个article中一样。从数据库(Hibernate)获取User列表并使用它填充DataGrid时遇到问题。当我调用greetingService.allUsers()方法时,我收到错误(onFailure()):

com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException:无法反序列化响应

有人帮忙吗?下面是一些代码。完整的工作项目是here

  public void onModuleLoad() {
    // ...
    greetingService.allUsers(
        new AsyncCallback<List<User>>(){
            @Override
            public void onFailure(Throwable caught) {
                caught.printStackTrace();
            }
            @Override
            public void onSuccess(List<User> result) {
                GWT.log("SIZE: "+result.size());
                dataGrid.setRowData(result);
            }
        }
    );
    // ...
 }

GreetingServiceImpl

@Override
public List<User> allUsers() {
    return userDAO.findAll();
}

用户

@Entity
@Table(name = "users")
public class User implements Serializable, IsSerializable {

    @Id
    private Long id;

    // only Strings and one Date
    private String login;
    private String password;
    private String firstname;
    private String lastname;
    private Date date;
}
gwt gwt2
8个回答
6
投票

IncompatibleRemoteServiceException的文档说:

此异常可能由以下问题引起:

  • 无法通过服务器上的{@link Class#forName(String)}找到请求的{@link RemoteService}。
  • 所请求的{@link RemoteService}接口未由配置为处理请求的{@link com.google.gwt.user.server.rpc.RemoteServiceServlet RemoteServiceServlet}实例实现。
  • 请求的{@link RemoteService}接口未定义或继承所请求的服务方法。

  • {@link RemoteService}方法调用中使用的其中一种类型已添加或删除了字段。
  • 客户端代码从服务器接收不能的类型 反序列化。

在你的情况下是最后一点,你有一个无法序列化和反序列化的类型,那就是你的User类就是其中之一。您应该有一个传输对象,它实现com.google.gwt.user.client.rpc.IsSerializable接口,以便通过网络传输User对象。有关详细信息,请参阅:Compatibility with the Java Language and Libraries。 GWT RPC方法参数和返回类型必须通过网络在客户端和服务器应用程序之间传输,因此它们必须是serializable


2
投票

我会尝试一些事情。

  • 在用户实现com.google.gwt.user.client.rpc.IsSerializable并添加一个空白构造函数。我记得很久以前在某处读过这是必要的,它在我的一个项目中解决了这样的问题。 public User(){}
  • 确保您的包在gwt.xml文件中定义。

你没有做任何不能序列化的复杂事情,所以你应该没问题。


1
投票

我根据GwtRpcController更新了this解决了我的问题。现在,反序列化在不使用任何传输对象的情况下运行良好。在下面工作GwtRpcController

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.google.gwt.user.server.rpc.RPCRequest;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class GwtRpcController extends RemoteServiceServlet implements
        Controller, ServletContextAware {

    private static final long serialVersionUID = 1L;

    private ServletContext servletContext;

    private RemoteService remoteService;

    private Class remoteServiceClass;

    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        super.doPost(request, response);
        return null;
    }

    @Override
    public String processCall(String payload) throws SerializationException {
        try {

            RPCRequest rpcRequest = RPC.decodeRequest(payload, this.remoteServiceClass, this);
            onAfterRequestDeserialized(rpcRequest);

            // delegate work to the spring injected service
            return RPC.invokeAndEncodeResponse(this.remoteService, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy());
        } catch (IncompatibleRemoteServiceException ex) {
            getServletContext().log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
            return RPC.encodeResponseForFailure(null, ex);
        }
    }

    @Override
    public ServletContext getServletContext() {
        return servletContext;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    public void setRemoteService(RemoteService remoteService) {
        this.remoteService = remoteService;
        this.remoteServiceClass = this.remoteService.getClass();
    }

}

0
投票

所有,花了很多时间,我有一个不同的解决方案。我使用的是一个非常简单的设置,我的POJO实际上只不过是成员和CTOR。

我重新创建了一个新的GWT项目并将我的东西添加回新项目中,重新添加了每个POM.xml依赖项。我发现maven编译器设置得太高了。我从另一个不考虑它的项目中复制了这个...... GWT客户端几乎只有1.5,可能是1.6兼容...所以这些设置需要设置为1.5,而不是1.7

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>2.3.2</version>
 <configuration>
  <source>1.7</source>                     <!-- change these to 1.5 -->
  <target>1.7</target>
 </configuration>
</plugin>

0
投票

当使用带有“提供”范围的guava-gwt时,我遇到了这个错误。为了在运行时满足依赖性,我添加了google-collections。 GWT客户端无法反序列化。

解决方案:删除依赖google-collections,并坚持使用番石榴。


0
投票

对于可序列化对象的问题,您可以尝试以下检查列表:

  1. 验证该类是否具有默认构造函数(不带参数)
  2. 验证该类是否实现Serializable或IsSerializable,或实现扩展Serializable的接口或扩展实现Serializable的类
  3. 验证该类是否在客户端。*包或...
  4. 验证,如果该类不在客户端。*包中,则在GWT xml模块定义中编译。默认情况下存在。如果您的班级在另一个包中,则必须将其添加到源。例如,如果您的类在域。*下,则应将其添加到xml中。请注意,该类不能属于服务器包!关于GWT页面的更多细节:http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
  5. 如果要包含来自另一个GWT项目的类,则必须将继承添加到xml模块定义中。例如,如果您的类Foo位于包com.dummy.domain中,则必须添加到模块定义中。更多细节在这里:http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
  6. 如果要包含来自另一个作为jar发布的GWT项目的类,请验证jar还包含源代码,因为GWT还重新编译传递给客户端的类的Java源代码。

字体:http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/


0
投票

我正在一个拥有成熟软件的团队工作,有一天因为这个错误而停止为我工作。团队的其他成员都很好。我们尝试了很多东西来解决它。最终,我们重新安装了IntelliJ并修复了它。


0
投票

有时此错误可能是由于过时/损坏的客户端文件/缓存(在这种情况下没有服务器端错误消息)。我刚刚在IntelliJ中运行了“rebuild module”,它又恢复了。

© www.soinside.com 2019 - 2024. All rights reserved.