2009-02-03 86 views
0

我目前正在考慮Java Swing WebStart應用程序(胖客戶端)和運行在Tomcat上的一些遠程服務之間的遠程處理/序列化的一些設計細節。我想使用一個http兼容的傳輸與服務器通信,因爲我已經使用Spring,我認爲Spring的HTTP Remoting是一個不錯的選擇。但我可以在這裏接受其他選擇。我的設計問題最好用一些小例子來說明使用遠程服務的Java序列化和實例共享

客戶端將在遠程端調用一些服務。示例服務接口:

public interface ServiceInterface extends Serialiazable { 
    // Get immutable reference data 
    public List<Building> getBuildings(); 
    public List<Office> getOffices(); 

    // Create, read and update Employee objects 
    public insertEmployee(Employee employee); 
    public Employee getEmployee(); 
    public void updateEmployee(Employee employee); 
} 

Building和Office是不可變的引用數據對象,例如,

public Building implements Serializable { 
    String name; 
    public Building(String name) { this.name = name; } 
    public String getName() { return name; } 
} 

public Office implements Serializable { 
    Building building; 
    int maxEmployees; 
    public Office(Building building, int maxEmployess) { 
     this.building = building; 
     this.maxEmployees = maxEmployees; 
    } 
    public Building getBuilding() { return building; } 
    punlic int getMaxEmployees() { retrun maxEmployees; } 
} 

可用的建築物和辦公室在運行時不會改變,應該由客戶來prefeteched有可供選擇的列表,過濾條件,......我想有每個特定的建築只有一個實例Office和客戶端以及一個實例在服務器端。在服務器端,這不是一個大問題,但在我眼裏,當我在getBuildings()之後調用getOffices()時,問題就從這裏開始。由getOffices()返回的建築物共享相同的建築物實例(如果它們具有相同的建築物分配),但由getOffices()返回的建築物(在Office對象中引用)與getBuildings()返回的建築物不同。

這可能是通過使用getReferenceDate()方法在同一個調用中返回兩個信息來解決的,但是如果我有員工引用辦公室,問題將會開始。

我正在考慮一些自定義序列化(readObject,writeObject)只傳遞主鍵,而不是從持有引用數據對象的某個類獲取對象的實例。但這是解決這個問題的最佳方案嗎?我認爲這個問題並不罕見,但在Google上沒有發現任何問題。有更好的解決方案嗎?如果不是,那麼實施它的最好方法是什麼?

回答

0

首先,我建議使用RMI來進行遠程處理,它可以通過HTTP(IIRC)進行代理。其次,如果序列化ServiceInterface,我相信序列化機制將維護在遠程JVM中反序列化時的相對引用。

1

如果你要序列化,您可能需要執行的readResolve保證你沒有創造額外的實例:

從Javadoc文檔Serializable接口

類需要當其實例爲 時,指定 替換應該實現 具有確切 簽名的這種特殊方法。

任意訪問修改器對象 readResolve()拋出 ObjectStreamException;

我似乎還記得在處理序列化對象時必須保證是單數的,例如類型安全枚舉,這個方法在枚舉前的日子裏是這樣的。

我還強烈建議您在序列化類中包含一個手動serialVersionUID,以便您可以手動控制應用程序何時決定您的類表示不能反序列化的不兼容版本。但是,在更基本的層面上,我會質疑整個方法 - 而不是試圖保證網絡上的對象身份,這聽起來至少是一個併發的噩夢,爲什麼不通過原始數據並通過你的邏輯來確定ID的身份,就像我在祖父的日子裏做的那樣?您的後端有一個構建對象,它從前端獲取一個,通過ID進行比較(如果您更改了前端上的對象,則必須將對象提交到中央數據存儲並確定哪些內容已更改,哪些可以成爲多個客戶端的同步問題,但無論如何你都會遇到這個問題)。

通過Spring-httpclient遠程傳遞數據很好很簡單,比RMI低一點。