2011-04-04 30 views
1

我在GWT中定義了一個簡單的「鍵值存儲」服務;我將寫服務器,但讓其他人編寫客戶端,以便儘可能簡單。我希望客戶端能夠使用String鍵,但是可以使用任何可序列化類型的值。所以我定義的接口:GWT-RPC服務應該使用java.io.Serializable作爲參數類型嗎?

public void put(String key, java.io.Serializable value); 
public java.io.Serializable get(String key); 

這工作完全,但有一個問題:Eclipse中給出了這兩種方法如下警告:

檢查其資格序列化對象的所有亞型

使用Google搜索警告,GWT似乎會爲程序中的每種類型生成一段代碼。因此,這可能相當昂貴。我很困惑,因爲我認爲Serializable接口中的所有類型都已經有序列化代碼,並且可以調用它(但也許該序列化代碼僅在此情況下生成)。

所以我有一些問題:

  • 難道這將會使客戶端代碼太大的)更大的和/或b)慢?這個問題有多嚴重?
  • 我看到GWT提供了一個單獨的界面IsSerializable。我可以用它來代替嗎?我嘗試過,但我注意到像String和Integer這樣的基本類沒有實現這個接口。
  • 如果我讓RPC層使用byte[]來代替,但是爲我的客戶端提供了一個包裝方法來將java.io.Serializable序列化爲byte[],那麼是否會解決問題,還是最終會出現與我開始的相同的代碼膨脹問題?
  • 有沒有更好的方式來實現一個鍵值存儲,它允許任意類型的值,而不需要代表客戶端做太多工作?
  • 如果我堅持使用Serializable,是否有辦法抑制這個警告?
+0

注意:至於抑制該警告,看起來目前沒有辦法做到這一點。有一個問題,[問題3501](https://code.google.com/p/google-web-toolkit/issues/detail?id=3501)。 – mgiuca 2011-04-04 14:17:00

回答

2

我看到GWT提供了一個單獨的接口IsSerializable。我可以用它來代替嗎?我嘗試過,但我注意到像String和Integer這樣的基本類沒有實現這個接口。

是的。 IsSerializable比java.io.Serializable更受歡迎。該GWT FAQ名單的原因是這樣:

  • GWT的序列化的語義是遠遠超過標準的Java序列化不太成熟,所以使用了java.io.Serializable作爲標記接口將意味着GWT的序列化系統能夠比實際情況更多。相反,GWT的序列化機制比標準Java更簡單,因此使用java.io.Serializable會意味着用戶需要比實際操作更多地擔心(比如序列化版本ID)。
  • GWT只實現完整的Java JRE類的一個子集,並且專門在java.io中實現任何內容。使用java.io.Serializable作爲GWT RPC序列化標記接口稀釋java的消息。io在GWT應用程序中不可用。

>

如果我做了RPC層使用字節[]而不是,而是爲我的客戶序列化的java.io.Serializable成字節[]的包裝方法,是否會解決這個問題,還是最終會出現與我開始的代碼膨脹問題?

壞主意。在這種情況下,從對象到byte []的序列化將在客戶端的JavaScript中發生。是的,序列化可能在客戶端,但與GWT協議;這不是Java序列化。瀏覽器不會那麼好。

有沒有更好的方法來實現一個鍵值存儲,它允許任意類型的值,而不需要代表客戶做太多的工作?

不幸的是,我認爲你將無法擺脫所有類的一個真正的方法。我建議你嘗試以下接口:

interface Store<T extends Serializable & IsSerializable> { 
void put(String key, String value); 
void put(String key, Number value); 
void put(String key, T value); 

Integer getInt(String key); 
Double getDouble(String key); 
BigDecimal getBigDecimal(String key); 
String getString(String key); 
IsSerializable get(String key); 
} 

仿製藥確保對象有兩個接口,這樣就可以與GWT協議序列,然後兩者(從客戶端到服務器)和Java序列化(從服務器到數據商店)。

編輯接聽評論:

與去年的解決方案,不通用的意思是店裏只能存儲一個類型的對象,並且如果客戶希望存儲不同的一個,他必須創建一個新的商店?

是的,客戶端必須爲每種類型創建一個新的商店。如果真的困擾你,解決這個問題的方法是創建一個新的接口MySerializable,它擴展了IsSerializable和java.io.Serializable;但是每個對象都必須實現它,這會對您的項目產生依賴關係。

也不需要對象是Serializable和IsSerializable?

是的,這是一個好處。否則,您有可能在服務器端有一個不是java.io.Serializable的對象;如果您嘗試將其提供給方法ObjectOutputStream#writeObject,則表面上會出現異常情況。

最後,我的第一個問題是什麼:只是使用io.Serializable實際上會影響代碼大小/性能?

我不能說從實際使用,但我不這麼認爲:兩者都只是標記接口。 GWT序列化也是一樣的。

+0

感謝您的建議。哎喲,看起來不像有一個簡單的出路。用最後一個解決方案,通用意味着商店只能存儲單一類型的對象,如果客戶想存儲不同的對象,他必須創建一個新的商店?也不要求對象是Serializable和IsSerializable?最後,我的第一個問題是:只是使用io.Serializable實際上會影響代碼大小/性能? – mgiuca 2011-04-04 13:58:03

+0

感謝您的額外信息。我認爲我會冒這個風險,只是使用java.io.Serializable,儘管有警告。但是,謝謝你清楚地解釋這個問題的所有方面。 – mgiuca 2011-04-05 06:25:53

相關問題