2012-01-20 103 views
6

我正在使用GWT(2.4),並將彈簧集成在此article中。我有從數據庫中獲取用戶列表(Hibernate)的問題,並用它填充DataGrid。當我打電話greetingService.allUsers()方法,我得到錯誤(onFailure處()):GWT:響應無法反序列化

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; 
} 

回答

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(); 
    } 

} 
6

爲IncompatibleRemoteServiceException文件說:

此異常可以通過以下問題引起的:

  • 請求的{@link RemoteService}無法通過服務器上的{@link Class#forName(String)}進行定位。
  • 請求的{@link RemoteService}接口不是由{@link com.google.gwt.user.server.rpc.RemoteServiceServlet RemoteServiceServlet}實例,其被配置來處理該請求 實現。
  • 所請求的服務方法未定義,或者請求的{@link RemoteService}接口繼承了 。

  • {@link RemoteService}方法 調用中使用的一種類型已添加或刪除了字段。
  • 客戶端 代碼從服務器收到一個類型,它不能
    反序列化。

在你的情況是最後一點,你不能被序列化和反序列化一個類型,這是一個你User類是其中之一。您應該有一個傳輸對象,它實現了用於跨網絡傳輸用戶對象的接口com.google.gwt.user.client.rpc.IsSerializable。欲瞭解更多信息,請參閱:Compatibility with the Java Language and Libraries。 GWT RPC方法參數和返回類型必須通過網絡在客戶端和服務器應用程序之間傳輸,因此它們必須是serializable

2

我會嘗試幾件事情。

  • 在用戶僅實現com.google.gwt.user.client.rpc.IsSerializable並添加空白構造。我記得很久以前在某個地方閱讀過,這是需要的,它在我的一個項目中解決了這樣的問題。 public user(){ }
  • 確保你的包是在你的gwt.xml文件中定義的。

你沒有做任何更復雜的事情,無法序列化,所以你應該沒問題。

+0

哦,那可怕的沒有參數構造函數已經得到了我很多次...它可以是私有的。 – DTing

+0

我有空白的構造函數。你的意思是:_「確保你的包是在你的gwt.xml文件中定義的」_? – marioosh

+0

在您的項目中,您將在src的底部有一個 .gwt.xml文件。在底部,你會看到我在說什麼。這裏有一個有用的鏈接:[路徑處理](http://code.google.com/p/google-web-toolkit-incubator/wiki/PathsHandlingFAQ) –

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客戶端無法反序列化這些。

解決方法:刪除依賴谷歌集合,並堅持使用番石榴。

0

要使用序列化對象的問題,你可以試試這個檢查表:

  1. 驗證類有一個默認的構造函數(不帶參數)
  2. 驗證類實現Serializable或IsSerializable或 實現了擴展序列化或擴展了實現Serializable
  3. 驗證類是在客戶端類 。*包或...
  4. 驗證,如果類爲n接口ot in client。*包,編譯於 您的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. 如果是包括釋放 另一個GWT項目類中的罐子驗證罐子還包含了源代碼,因爲GWT 也重新編譯Java源代碼傳遞給客戶端的類。

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

0

我在一隊有成熟的軟件哪一天停止工作對我來說,由於這個錯誤的工作。團隊的其他成員都很好。我們嘗試了許多事情來解決它。最終,我們重新安裝了IntelliJ並修復了它。

0

有時候,這個錯誤可能是由於過時/損壞的客戶端文件/緩存(在這種情況下沒有服務器端錯誤消息)。我只是在IntelliJ中運行「重建模塊」,並且再次正常。