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



编辑:Java™教程说

服务器和客户端进行通信并将信息传递回第四

和RMI

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

我希望"对象的数据"包括服务器对象的变量(如下面代码中的Test.value),但我得到的第一条注释表明我可能错了。我最初的问题如下。

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

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

附言:在上面的客户端代码中,test.shortName有一个摆动的下划线,Eclipse建议使用The static field TESTint.shortName should be accessed in a static way。我知道客户端不识别实现,只识别接口,但有没有一种方法可以访问测试的字段,而不仅仅是它的方法?我的原始代码中有很多字段,如果可能的话,我不想为每一个字段都写getter。

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

相关内容

最新更新