使用远程服务的Java序列化和实例共享

使用远程服务的Java序列化和实例共享,java,serialization,remoting,Java,Serialization,Remoting,我目前正在考虑Java Swing WebStart应用程序(胖客户端)和Tomcat上运行的一些远程服务之间的远程处理/序列化的一些设计细节。我想使用http兼容的传输与服务器通信,因为我已经在使用Spring,所以我认为Spring的http远程处理是一个不错的选择。但我对其他选择持开放态度。我的设计问题最好用一些小例子来说明 客户端将调用远程端的一些服务。示例服务接口: public interface ServiceInterface extends Serialiazable {

我目前正在考虑Java Swing WebStart应用程序(胖客户端)和Tomcat上运行的一些远程服务之间的远程处理/序列化的一些设计细节。我想使用http兼容的传输与服务器通信,因为我已经在使用Spring,所以我认为Spring的http远程处理是一个不错的选择。但我对其他选择持开放态度。我的设计问题最好用一些小例子来说明

客户端将调用远程端的一些服务。示例服务接口:

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);
}
可用的建筑物和办公室在运行期间不会改变,应由客户预先检测,以获得可用的选择列表、过滤条件等。。。我只希望在客户端和服务器端各有一个特定建筑和办公室的实例。在服务器端,这不是一个大问题,但在我看来,当我在getBuildings()之后调用getOffices()时,问题就从这里开始了。GetOffice()返回的建筑共享相同的建筑实例(如果它们指定了相同的建筑),但GetOffice()返回的建筑(在Office对象中引用)与getBuildings()返回的建筑实例不同

这可以通过使用一些getReferenceDate()方法在同一个调用中返回这两个信息来解决,但是如果我让员工引用Office,问题就会开始


我在考虑一些自定义序列化(readObject,writeObject),只传输主键,而不是从某个包含引用数据对象的类中获取对象的实例。但这是解决这个问题的最好办法吗?我认为这个问题并不罕见,但在谷歌上没有发现任何东西。有更好的解决办法吗?如果没有,最好的实现方法是什么?

首先,我建议您使用for-your-remoting,它可以通过HTTP(IIRC)进行代理。其次,如果序列化ServiceInterface,我相信序列化机制将在远程JVM中对其进行反序列化时维护相对引用。

如果要序列化,可能需要实现readResolve以确保不创建其他实例:

从可序列化的javadoc:

需要指定 当它的一个实例 从流中读取应该实现 这种特殊的方法具有精确的精度 签名

任意访问修改器对象 readResolve()抛出 对象异常

我似乎还记得在枚举之前的日子里读过关于这种方法的书,这种方法用于处理必须保证是单数的对象的序列化,比如类型安全枚举

我还强烈建议您在序列化的类中包含手动serialVersionUID,以便您可以手动控制应用程序何时决定您的类表示无法反序列化的不兼容版本

然而,在一个更基本的层面上,我会质疑整个方法,而不是试图通过网络保证对象的身份,这听起来至少是并发性的噩梦,为什么不只是传递原始数据,让您的逻辑通过id确定身份,就像我们在我祖父的时代那样?您的后端有一个建筑对象,它从前端获得一个,通过ID进行比较(如果您更改了前端的对象,则必须将对象提交到您的中心数据存储并确定更改了什么,这可能是与多个客户端的同步问题,但无论如何您都会遇到该问题)

通过SpringHttpClient远程传递数据既好又简单,比RMI低一点

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