java RMI客户端也要实现服务端的接口吗
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
public class Sever {
public static void main(String[] args) {
String host = "localhost";
try {
TestSever ts = new TestImpl();
TestSever stub = (TestSever) UnicastRemoteObject.exportObject(ts, 0);
LocateRegistry.createRegistry(40000);
LocateRegistry.getRegistry(40000).bind(host, stub);
System.out.println("Sever started sussessful!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是客户端获得服务端类的代码
Registry r = LocateRegistry.getRegistry("localhost", 40000);
TestSever s = (TestSever) r.lookup("localhost");
在客户端的工程中必须也要有TestSever和TestImpl两个类,没有的话
TestSever s = (TestSever) r.lookup("localhost"); 会报错。
这是为什么????
求大神解答啊,小弟感激不尽!!! 展开
两边是通过接口来交换信息的,当然都需要接口和它的 Stub。
你做实验时可以考虑创建3个项目:
1、接口项目,只包括接口和接口编译后的 Stub 类
2、服务端项目,只包括服务器类,它依赖接口项目。
3、客户端项目,只包括客户端,它依赖接口项目。
如果是从命令行运行它们,那么服务端需要服务端项目和接口项目两个 jar,客户端需要客户端项目和接口项目两个 jar,我们需要面向接口编程减少耦合程度,不要把所有类全部放在同一个项目中编译,将来会碰到很多麻烦事,比如包名太多就可能不支持 OSGi 这种方式。
在远程调用类的应用中,使用静态方法调用时一般需要接口类对应的Stub,我们 lookup 得到的其实是 Stub (它只包括了连接到服务器的参数,然后把你想调用的”服务“ + ”参数“ 发送给服务器并将从服务器返回的结果返回给客户端程序,因此,它其实并没有什么”针对你的程序和服务器的特殊特性),使用动态的调用方式就完全可以做到不需要特定的 Stub 而用一个通用的方式 (也就是 RMI 编译生成的那个 Stub 类的内容我们来自己写成一个框架。
上面一段是废话,来说说怎么配置环境测试它们。
客户端项目中只需要有接口 TestServer 和 TestServerStub 两个类,如果你的参数本身也是一个 Remote 子类,那么参数类也需要有相应的 Stub。
另外,我们客户端也可以仅自带接口类而不自带Stub,在运行的时候可以”请求从服务器上下载一份 Stub",如下:
System.setSecurityManager(new RMISecurityManager());
然后在命令行添加额外参数:
-Djava.security.policy=$policy 文件
-Djava.rmi.server.codebase=file:///C:/service-interface/classes/
这样就可以启用 RMI Class Loader 来自动从 codebase 对应的地方查找 Stub 类,这里面 codebase 可以是一个 Http 或 Ftp 协议,注意这个 codebase URL 后面一个 / 是必须的。那个 $policy 文件可以用 JDK\bin\policytool.exe 来生成一个。