1. Java远程方法调用(RMI)提供了Java程序语言的远程通讯功能,
这种特性使客户机上运行的程序可以调用远程服务器上的对象,
使Java编程人员能够在网络环境中分布操作。
三、编写服务器类:
二是调用服务器远程对象上的远程方法。
这种特性使客户机上运行的程序可以调用远程服务器上的对象,
使Java编程人员能够在网络环境中分布操作。
2.创建一个简单的Java分布式远程方法调用程序可以按以下几个步骤操作,
package my.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 在 Java 中,远程对象是实现远程接口的类的实例, 远程接口声明每个要远程调用的方法。
* 在需要创建一个远程对象的时候,我们通过传递一个接口来隐藏基层的实施细节,客户通过接口句柄发送消息即可。
* 远程接口具有如下特点:
* 1) 远程接口必须为public属性。如果不这样,除非客户端与远程接口在同一个包内,
* 否则 当试图装入实现该远程接口的远程对象时,调用会得到错误结果。
* 2) 远程接口必须扩展接口java.rmi.Remote。
* 3) 除与应用程序本身特定的例外之外,远程接口中的每个方法都必须在自己的throws从句中
* 声明java.rmi.RemoteException。(或 RemoteException 的父类)。
* 4) 作为参数或返回值传递的一个远程对象(不管是直接,还是本地对象中嵌入)必须声明为远 程接口,
* 而不应声明为实施类。
* @author Wang 2014年4月30日
*
*/
public interface MyRmiService extends Remote{
/**
* 加法
* @param x
* @param y
*/
public Integer addition(Integer x,Integer y)throws RemoteException;
/**
* 减法
* @param x
* @param y
*/
public Integer subtraction(Integer x,Integer y)throws RemoteException;
/**
* 乘法
* @param x
* @param y
*/
public Integer multiplication(Integer x,Integer y)throws RemoteException;
/**
* 除法
* @param x
* @param y
*/
public Integer division(Integer x,Integer y)throws RemoteException;
}
二、实现远程接口:
package my.rmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* 远程对象实现类必须扩展远程对象java.rmi.UnicastRemoteObject类,并实现所定义的远程接口。
* 远程对象的实现类中包含实现每个远程接口所指定的远程方法的代码。这个类也可以含有附加的方法,
* 但客户只能使用远程接口中的方法。因为客户是指向接口的一个句柄,而不是它的哪个类。必须为远程对象
* 定义构造函数,即使只准备定义一个默认构造函数,用它调用基础类构造函数。因为基础类构造函数可能会
* 抛出 java.rmi.RemoteException,所以即使别无它用必须抛出java.rmi.RemoteException例外。
* @author Wang 2014年4月30日
*
*/
public class MyRmiServiceImpl extends UnicastRemoteObject implements MyRmiService{
private static final long serialVersionUID = 1L;
protected MyRmiServiceImpl() throws RemoteException {
super();
}
@Override
public Integer addition(Integer x, Integer y) throws RemoteException {
return x+y;
}
@Override
public Integer subtraction(Integer x, Integer y) throws RemoteException {
return x-y;
}
@Override
public Integer multiplication(Integer x, Integer y) throws RemoteException {
return x*y;
}
@Override
public Integer division(Integer x, Integer y) throws RemoteException {
if(y!=0){
return x/y;
}else{
return 0;
}
}
}
三、编写服务器类:
package my.rmi;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
/**
* 包含 main 方法的类可以是实现类自身,也可以完全是另一个类。
* 下面通过RmiSampleServer 来创建一个远程对象的实例,并通过java.rmi.registry.LocateRegistry类
* 的createRegistry 方法从指定端口号启动注册服务程序,也可以通过执行 rmiregistry 命令启动注册服
* 务程序,注册服务程序的缺省运行端口为 1099。必须将远程对象名字绑定到对远程对象的引用上:
* @author Wang 2014年4月30日
*/
public class MyRmiServer {
public static void main(String[] args) {
try {
MyRmiService rmiService=new MyRmiServiceImpl();
//注册通讯端口
LocateRegistry.createRegistry(6600);
/**
* 注册通讯路径
* 6600端口不能被其他进程占用,MyRmiService貌似可以随意,最好用你的service类名。
*/
Naming.rebind("rmi://127.0.0.1:6600/MyRmiService", rmiService);
System.out.println("Service Start!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
四、编写使用远程服务的客户机类
二是调用服务器远程对象上的远程方法。
package my.rmi;
import java.rmi.Naming;
import java.rmi.RemoteException;
public class MyRmiClient {
public static void main(String[] args) {
add(1,2,1);
}
public static void add(int a,int b,int c){
//如果c==1,执行执行本地程序,否则远程调用程序。
if(c==1){
try {
MyRmiService rmiService = new MyRmiServiceImpl();
System.out.println(" 1 + 2 = " + rmiService.addition(1, 2));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
/**
* IP为你的代理机的IP地址,即如果在本机运行的远程代理服务,则为
* 你的本机IP,如果在虚拟机运行的远程代理服务,则为你的虚拟机IP。
*/
String url = "rmi://172.16.12.215:6600/MyRmiService";
MyRmiService rmiService = (MyRmiService)Naming.lookup(url);
System.out.println(" 1 + 2 = " + rmiService.addition(1, 2));
} catch (RemoteException rex) {
System.out.println("Error in lookup: " + rex.toString());
} catch (java.net.MalformedURLException me) {
System.out.println("Malformed URL: " + me.toString());
} catch (java.rmi.NotBoundException ne) {
System.out.println("NotBound: " + ne.toString());
}
}
}
}
3.现在所有代码都已经完成,然后导出jar文件,main入口指向MyRmiServer的main方法。可以在本机或虚拟机上运行jar文件。
命令为:java -jar rmi.jar
然后执行MyRmiClient的方法测试远程调用是否成功。