本文讨论的内容:
- 1、什么是RMI
- 2、RMI的作用和用途
- 3、RMI的运行步骤和实现代码
- 4、RMI优势与劣势的分析
一、什么是RMI 远程方法调用(文档描述)。客户端远程调用服务器端的方法,得到方法的结果(返回值)。这里不花多功夫解释,相信我们在进行代码的分析和运行后会了解什么是RMI。
二、RMI的作用和用途
初学RMI,它能够帮助我们查找并执行远程对象的方法。通俗地说,远程调用就象将一个class放在A机器上,然后在B机器中产生一个代理对象来调用这个class的方法。目前我认为它的作用就是,远程调用方法,实现分布式。
三、RMI的运行步骤和实现代码
1、编写服务器端要被客户端远程调用的对象的接口,这里例如是ServiceInterface。必需继承Remote接口。
package cn.netjava.ml.jdkrmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* RMI调用对象接口定义
* @author ml
*
*/
public interface ServiceInterface extends Remote{
/**
* 继承于他的远程服务对象所必需实现的方法
* 所有远程服务的方法都必需声明异常
* @param object
* @return
* @throws RemoteException
*/
Object service(Object object) throws RemoteException;
}
Remote 是RMI中一个空的接口
Object service(Object object)
throws RemoteException 是我们自定义的一个方法,在将来可以被客户端远程调用,返回客户端想得到的对象,当然可以是空。这里注意必需声明RemoteException 异常。
2、编写要被远程调用对象接口的实现类
package cn.netjava.ml.jdkrmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* RMI服务对象接口实现,此对象将被RMI服务器导出做为远程服务对象
*
* @author ml
*
*/
public class ServiceImp extends UnicastRemoteObject implements ServiceInterface {
/**
*
*/
private static final long serialVersionUID = -2212782652822117319L;
/**
* 父类构造器
*
* @throws RemoteException
*/
protected ServiceImp() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
/**
* 客户端将要调用的方法
*/
@Override
public Object service(Object object) throws RemoteException {
// TODO Auto-generated method stub
System.out.println(object);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return object + " " + System.currentTimeMillis();
}
}
除了继承服务对象接口外还要继承UnicastRemoteObject类。这里必须要有的一个是构造器,一个是重写service方法。构造器里面调用super()。查查源码就知道super是指UnicastRemoteObject导出了这个服务对象(serviceImp)。service方法就是将来要被客户端调用的方法,这服务器端执行。
3、编写服务启动类
package cn.netjava.ml.jdkrmi;
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.ServerNotActiveException;
/**
* 启动RMI服务器导出服务对象
*
* @author Administrator
*
*/
public class ServiceStart {
public static void main(String[] args) {
int listenPort = 9003;
String serverIP = "localhost";
// 要导出服务对象的名字
String serverObjName = "serverObjName";
// 设置RMI服务监听端口
LocateRegistry.createRegistry(listenPort);
// 设置日志
ServiceImp.setLog(System.out);
// 创建要导出的服务对象,并绑定服务
ServiceImp remoteObj = new ServiceImp();
try {
Naming.rebind("rmi://" + serverIP + ":" + listenPort + "/"
+ serverObjName, remoteObj);
System.out.println("RMI服务启动了");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
代码有注释,这里不多做解释了。
4、编写客户端要调用远程对象的接口
这里看起来好像不太明白。简单解释是这样的,客户端要远程调用服务器对象的方法,首先客户端必须要有要被远程调用的对象的接口。这里直接把服务器端的那个ServiceInterface复制过来就行了。有一点必须注意的是。
这个接口名以及接口所在的包名必需和服务器端一样!!这里就不贴代码了。
5、编写客户端远程调用类
package cn.netjava.ml.jdkrmi;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
*
* @author ml
*
*
*报名要和服务器端相同
*/
public class RMIClient {
public static void main(String[] args) {
int listenPort = 9003;
String serverIP = "localhost";
String serverObjName = "serverObjName";
try {
ServiceInterface remote = (ServiceInterface) Naming
.lookup("rmi://" + serverIP + ":" + listenPort + "/"
+ serverObjName);
for (int i = 0; i < 3; i++) {
//客户端还是要有ServiceInterface对象~~~~
Object object = remote.service("我是远程客户"+i);
System.out.println("客户端调用远程方法了");
System.out.println("远程服务应答"+object);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6、服务器端编译桩,并把生成的桩复制在客户端的bin目录下
进入windows命令行或linux命令终端。输入rmic。有反应了吧,这就是编译桩的工具和javac类似。如果没有的话可能没有配环境变量。我们先编译生成所有类的class文件,再用cd命令进入工程的bin目录,之后使用rmic cn.netjava.ml.jdkrmi.ServiceImp 命令。
这里一定要加上包名(cn.netjava.ml.jdkrmi)。之后会生成ServiceImp_Stub.class文件,把他复制到客户端的class文件目录里就完成了。
7、分别运行服务器和客户端进行测试
四、RMI优势与劣势的分析
优势:RMI提供了java的远程方法调用,给java的分布式带来了方便。
劣势:个人认为RMI用的还是比较少的。
1、RMI仅仅是JAVA的实现,如果服务器是java,客户端是C++就不行了
2、RMI基于C/S模型 比不上基于B/S模型的其他框架实现如(Hessian和Burlap)。
分享到:
相关推荐
java rmi java rmijava rmi javajava rmi java rmi rmi
RMI简单实例RMI简单实例RMI简单实例
完整的Rmi调用示例,极难得的Rmi应用示例
rmi的详细例子,rmi的详细用法,一看就懂
RMI 规范 RMI 详细介绍 共10章
RMI教程 Java RMIRMI教程 Java RMIRMI教程 Java RMIRMI教程 Java RMIRMI教程 Java RMI
rmi小程序,RMI文档,为RMI初学者使用
RMI远程方法调用RMI远程方法调用RMI远程方法调用RMI远程方法调用RMI远程方法调用
1. Unpack RMI.rar and put the package "features" and "plugins" under the package "net.genady.rmi_2.0.2.1" to <%eclipse%> directory; 2. Copy rmi.jar and lic.jar under the package "crack" to ...
Spring-RMI (RMI调用, HTTP调用) 本人测试过了
本项目使用socket直接发送数据包来攻击rmi,通过反序列化攻击rmi,双击直接运行,对1099端口的rmi服务直接进行漏洞检测。
java rmi上传文件 在这次的项目中,对于客户端与服务器之间的通信,想了许多办法,由于做的是富客户端应用,最终将技术选定在了RMI和Java-sockets两种之间,其中RMI的灵活性不高,客户端和服务器端都必须是java编写...
Weblogic Server与RMI RMI的使用介绍
RMI远程文件传输
java RMI
Java编程rmi实例,给出远程方法调用技术在java方面的具体例子。
spring RMI 简单例子
web服务器 RMI meeting sokect
分布式实验报告RMI.docx
Java中RMI的实现机制Java中RMI的实现机制Java中RMI的实现机制Java中RMI的实现机制