2010-06-17 62 views
13

我有以下方法的RPC服務:gwt - 在RPC調用中使用List <Serializable>?

public List<Serializable> myMethod(TransactionCall call) {...} 

,但我得到時,分析了該方法的警告,然後將RPC調用失敗

Analyzing 'my.project.package.myService' for serializable types 
Analyzing methods: 
public abstract java.util.List<java.io.Serializable> myMethod(my.project.package.TransactionCall call) 
Return type: java.util.List<java.io.Serializable> 
[...] 
java.io.Serializable 
Verifying instantiability 
(!) Checking all subtypes of Object wich qualify for serialization 

看來我不能使用Serializable爲我的列表...我可以使用我自己的接口,而不是(像AsyncDataInterface,這實現了Serializ但實際上我的方法會返回一個列表自定義對象和基本對象(如Strings,int ....)。

所以我的問題是:

  • 它是一個非標準的行爲呢? (我不明白爲什麼我不能在這種情況下使用此接口)
  • 有沒有人有這種情況的解決方法?

回答

27

當在RPC調用中傳遞對象時,在RPC接口中聲明具體的參數類型是一種很好的做法。如果由於某種原因,您不能在RPC界面中使用具體類,儘可能使其具體。

這是因爲GWT編譯器在發射javascript時必須考慮編譯單元中List的所有可能變體。這包括在類路徑中擴展List和Serializable接口的所有類。排列可能很大,這會影響您的編譯時間以及應用程序下載大小。

所以最好的方法是定義你的界面

public ArrayList<YourType> myMethod(TransactionCall call) {...} 

而不是

public List<Serializable> myMethod(TransactionCall call) {...} 

這樣編譯器來生成唯一的ArrayList和YourType擴展編譯單元。好處是編譯速度更快,編譯的JavaScript文件更小,因此可以更快地下載應用程序。

如果您必須在RPC調用中返回大量不相關的對象,請嘗試創建包裝類並返回包裝類的返回對象。在RPC方法定義中使用包裝類。抵制將包裝字段聲明爲Object或Serializable的衝動,您將否定使用包​​裝器獲得的所有序列化好處。相反,您可以爲每個想要通過RPC調用返回的具體類型定義一個Wrapper接口和一小部分Wrapper實現。

1

您可能想要檢查序列化策略文件是否不是問題的根源。

Quote from GWT documentation

然而,有一個條件,以便能夠在新的GWT的RPC系統的java.io.Serializable支持。

RPC現在在GWT編譯期間生成序列化策略文件。序列化策略文件包含可以序列化的允許類型的白名單。它的名字是一個強大的散列名稱,後跟.gwt.rpc。爲了支持java.io.Serializable,應用程序將通過線路發送的類型必須包含在序列化策略白名單中。此外,序列化策略文件必須作爲公共資源部署到您的Web服務器,可以通過ServletContext.getResource()從RemoteServiceServlet訪問。如果沒有正確部署,RPC將以1.3.3兼容模式運行,並拒絕序列化實現java.io.Serializable的類型。

0

我沒有看到定義列表< Serializable>作爲返回值的要點。 Serializable類型在服務API聲明中不提供附加信息。無論如何,GWT將在運行時進行序列化檢查。

在你的情況下,列表元素除了Object之外沒有共同的祖先,我會使用List <?>。