通过RMI传输对象的数据(特别是服务器变量)

时间:2016-05-28 05:00:10

标签: java rmi

修改Java™ Tutorials

  

服务器和客户端进行通信并传回信息   所述

和那个RMI

  

还提供了加载对象类定义的机制   至于传输对象的数据。

我希望“对象的数据”包含服务器对象的变量(例如我的代码中的Test.value) - 但是我得到的第一条评论表明我可能错了。我原来的问题如下。

我正在尝试访问我通过RMI发送到客户端的远程对象。我只能访问它的方法,但不能访问它的实例变量 - 我得到了接口的字段。我的问题是,一旦我在服务器上实现并实例化一个类,如何在不使用getter的情况下访问其[public]字段?我能够发送没有任何错误或异常的存根,但就像我说的,我无法访问服务器的对象的字段,只能访问接口。以下是我的界面,实现,服务器和客户端的缩写版本。

package test;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface TESTint extends Remote {

        double value = -22;
        String shortName = "TESTint";

        double getValue() throws RemoteException;
}
package test;

import java.rmi.RemoteException;

public class Test implements TESTint {

    public double value = -33;
    public String shortName = "TestAccount";
    public int whole = 1;

    public Test(String shortName) {
        this.shortName = shortName;
        print(shortName);
    }

    public double getValue() throws RemoteException {
        return value;
    }

    public void print(Object o) {
        System.out.println(shortName + ": " + o);
    }   
}
package test;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class RemoteTestMain {
    Test test;

    public static void main(String[] args) throws InterruptedException {
        if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
        new RemoteTestMain();
    } // main

    public RemoteTestMain() {
        test = new Test("Charlie");
        Registry registry;
        try {
            registry = LocateRegistry.createRegistry(1234);
            registry.list( ); // will throw an exception if the registry does not already exist         
            print(test.shortName); // it gets it right here
            print(test.value); // it gets it right here
            TESTint r = (TESTint) UnicastRemoteObject.exportObject(test, 0);
            registry.rebind("DCregistry", r);
            print("test bound");  
        } catch (java.rmi.RemoteException ex) {
            print("Remote Exception at Server");
            ex.printStackTrace();;
        }
    }

    public static void print(Object o) {
        System.out.println("Server: " + o);
    }
}
package test;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
    TESTint test;

    public static void main(String[] args) {
        try {
            new Client();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    } // main

    private void init(int account) {
        print("INITiating Account " + account);         
        try {
            Registry registry = LocateRegistry.getRegistry(1234);
            test = (TESTint) registry.lookup("DCregistry");
        } catch (Exception e) {
            System.err.println("RMI exception:");
            e.printStackTrace();
        }
        print("Short name : " + test.shortName);
        print("value: " + test.value);
        try {
            print("Value through getter is " + test.getValue());
        } catch (RemoteException e) {
            print("Could not get equity");
            e.printStackTrace();
        }
    } // init(int account)

    public Client() throws RemoteException { 
        if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
        init(2);
    }

    private static void print(Object o) {
        System.out.println("GUI: " + o);
    }
}

P.S。在上面的客户端代码中,test.shortName带有下划线,Eclipse表示The static field TESTint.shortName should be accessed in a static way。我知道客户端不承认实现,只识别接口 - 但有没有办法访问测试的字段,而不仅仅是它的方法?我的原始代码中有很多字段,如果可能的话,我不想为每一个编写getter。

1 个答案:

答案 0 :(得分:1)

RMI代表Remote Method Invocation,这意味着您可以远程执行对象的方法。该方法的实现驻留在远程系统中。您永远不能访问远程系统中存在的实现类的实例变量,即使它们是公共的。您只能执行由Inteface公开的公共方法。因此,如果要访问变量,则需要在Inteface和实现类中添加public gettter方法。