问题在于使用RMI进行客户端 - 服务器通信 - 我不知道如何返回在服务器空间上运行的对象(或对象的引用),返回客户端,我可以使用其方法然后从该客户端打电话。我需要这个,因为基本的RMI示例只是将字符串或int等数据从服务器传递到客户端,而不是在服务器上运行的完全序列化的对象。
我发现的唯一类似问题是is it possible to pass by reference in RMI?
我想做的是:
服务器:创建并导出远程对象(实现远程接口)。客户端调用此远程对象的方法。此方法依次创建另一个类的新对象并返回对它的引用。
客户端:从Java RMI注册表获取存根。根据远程对象规范调用存根,并获取另一个对象的句柄,然后使用此句柄调用在服务器空间中运行的此对象的方法。
这甚至可能吗?我可能也错过了一两个概念。
代码:
//Hello.java
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
public target sayHello() throws RemoteException;
}
//Server.java
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server implements Hello {
public target t;
public Server() {}
public target sayHello() {
target t = new target(1,"target");
return t;
}
public static void main(String args[]) {
Hello stub = null;
Registry registry = null;
try {
Server obj = new Server();
stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
try{
registry.unbind("Hello");
registry.bind("Hello",stub);
System.err.println("Server ready");
}catch(Exception ee){
System.err.println("Server exception: " + ee.toString());
ee.printStackTrace();
}
}
}
}
//Client.java
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
target response = stub.sayHello(); //**Error string cannot be converted to type** target while compiling with javac
System.out.println("response: " + response.getdesc());
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
//target.java
import java.io.*;
class target implements Serializable {
int data;
String desc;
target(int data, String desc) {
this.data = data;
this.desc = desc;
}
public int getdata() { return data; }
public String getdesc() { return desc; }
public void setdata(int data) { this.data = data; }
public void setdesc(String desc) { this.desc = desc; }
}
答案 0 :(得分:1)
您只需要确保您返回的对象是导出的远程对象,并且在远程接口中引用它,并通过其自己的远程接口名称而不是自己的名称返回它。
答案 1 :(得分:1)
抱歉,我不明白你的整个问题,但RMI有2个选项。
如果您对特定的类方法感兴趣,可以使用接口对在Server的方法'sayHello'上创建的对象执行代理
这样的事情:
public interface TargetInterface extends Remote {
public void doSomething() throws RemoteException;
}
public Target extends UnicastRemoteObject implements TargetInterface {
private static final long serialVersionUID = 7204253532056038242L;
public Target() throws RemoteException {
super();
}
@Override
public void doSomething() throws RemoteException {
//TODO
}
}
在你的方法中,你应该返回TargetInterface。
否则,如果你想知道所有对象结构,你的对象应该是Serializable:
public class Target implements Serializable
这是你想要的东西吗?