JAVA RMI远程方法调用简单实例

来源:互联网 发布:java面向对象的代码 编辑:程序博客网 时间:2024/06/05 02:33

RMI的概念

RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。使用这种机制,某一台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据。RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote Procedure Call)应运而生,它使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持,而且RPC未能做到面向对象调用的开发模式。针对RPC服务遗留的问题,RMI出现在世人面前,它被设计成一种面向对象的通讯方式,允许程序员使用远程对象来实现通信,并且支持多线程的服务,这是一次远程通讯的革命,为远程通信开辟新的里程碑

RMI的开发步骤

  1. 先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote
  2. 开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject
  3. 通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象
  4. 最后客户端查找远程对象,并调用远程方法

简单实例

首先为服务建立一个Model层,注意因为此对象需要现实进行远程传输,所以必须继承Serializable

package com.partner.core.util;

import java.io.Serializable;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;


public class ResultVO implements Serializable{
/**
*
*/
private boolean ret;
/**
* 如果ret不为0,会有相应的错误信息提示
*/
private String msg;
/**
* 对象数据
*/
private Object data;


public boolean isRet() {
return ret;
}


public void setRet(boolean ret) {
this.ret = ret;
}


public String getMsg() {
return msg;
}


public void setMsg(String msg) {
this.msg = msg;
}


public Object getData() {
return data;
}


public void setData(Object data) {
this.data = data;
}


@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}


创建远程接口ISendMessage,注意远程接口需要继承Remote

package com.partner.rmi;


import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;


import com.partner.core.util.ResultVO;




/**
 * @filename      : ISendMessage.java
 * @description   : 描述(中文) :一定要throws RemoteException ,否则报错remote object implements illegal remote interface; nested exception is:
 * @author        : lvyuanjun
 * @create        : 2015年12月22日 下午3:05:36 
 * 
 * Modification History:修改日志
 * Date                 Author       Version               description
 * -------------------------------------------------------------------------------
 * 2015年12月22日 下午3:05:36      lvyuanjun
 */
public interface ISendMessage extends Remote{

public ResultVO sendMessage(String window_title,String tips_title,String tips_content,String tips_url,int companyId,List<Integer> employeeIds) throws RemoteException;
}


建立SendMessageImpl实现远程接口,注意此为远程对象实现类,需要继承UnicastRemoteObject

package com.partner.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;


import com.partner.core.util.ResultVO;

/**
 * @filename      : SendMessageImpl.java
 * @description   : 描述(中文)
 * @author        : lvyuanjun
 * @create        : 2015年12月22日 下午3:07:52 
 *
 * Modification History:修改日志
 * Date                 Author       Version               description
 * -------------------------------------------------------------------------------
 * 2015年12月22日 下午3:07:52      lvyuanjun
 */
public class SendMessageImpl extends UnicastRemoteObject implements ISendMessage {

/**
* @throws RemoteException
*/
public SendMessageImpl() throws RemoteException {

}


/**
* @author lvyuanjun
* @description 描述
* @createTime 2015年12月22日 下午3:08:38

*/
@Override
public ResultVO sendMessage(String window_title, String tips_title,
String tips_content, String tips_url, int companyId,
List<Integer> employeeIds) {

System.out.println("window_title:"+window_title);
System.out.println("tips_title:"+tips_title);
System.out.println("tips_content:"+tips_content);
System.out.println("tips_url:"+tips_url);
System.out.println("companyId:"+companyId);
System.out.println("employeeIds:"+employeeIds);

ResultVO result = new ResultVO();
result.setRet(true);
result.setMsg("正常");
result.setData("");

return result;
}
}



建立服务器端,在服务器端注册RMI通讯端口与通讯路径,由于本人是使用web服务器发布测试的,所以必须在启动服务器的时候调用initRMIServer()

public  void initRMIServer() {
try{
//创建一个远程对象
IHello rhello = new HelloImpl();

ISendMessage rSendMessage = new SendMessageImpl();
//本地主机上的远程对象注册表Registry的实例,并指定端口为8888,这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上 
            LocateRegistry.createRegistry(4321); 
            
            //把远程对象注册到RMI注册服务器上,并命名为RHello 
            //绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略,下面两种写法都是正确的) 
            
            String RMIURL = "rmi://localhost:4321/"; 
            
            Naming.bind(RMIURL+"RHello",rhello); 
            Naming.bind(RMIURL+"RSendMessage",rSendMessage);
            System.out.println(">>>>>INFO:远程IHello对象绑定成功!"); 
            
}catch (RemoteException e) { 
            System.out.println("创建远程对象发生异常!"); 
            e.printStackTrace(); 
        } catch (AlreadyBoundException e) { 
            System.out.println("发生重复绑定对象异常!"); 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            System.out.println("发生URL畸形异常!"); 
            e.printStackTrace(); 
        } 
}



客户端:

最后建立客户端进行测试,注意客户调用的RMI路径必须服务器配置一致,

如果model必须序列化Serializable,接口一定要和服务器保持一致。

model实体:

package com.partner.core.util;


import java.io.Serializable;


import org.apache.commons.lang3.builder.ReflectionToStringBuilder;


public class ResultVO implements Serializable{
/**
*
*/
private boolean ret;
/**
* 如果ret不为0,会有相应的错误信息提示
*/
private String msg;
/**
* 对象数据
*/
private Object data;


public boolean isRet() {
return ret;
}


public void setRet(boolean ret) {
this.ret = ret;
}


public String getMsg() {
return msg;
}


public void setMsg(String msg) {
this.msg = msg;
}


public Object getData() {
return data;
}


public void setData(Object data) {
this.data = data;
}


@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}


接口:

package com.partner.rmi;


import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;

/**
 * @filename      : ISendMessage.java
 * @description   : 描述(中文)
 * @author        : lvyuanjun
 * @create        : 2015年12月22日 下午3:05:36 
 *
 * Modification History:修改日志
 * Date                 Author       Version               description
 * -------------------------------------------------------------------------------
 * 2015年12月22日 下午3:05:36      lvyuanjun
 */
public interface ISendMessage extends Remote{

com.partner.core.util.ResultVO sendMessage(String window_title,String tips_title,String tips_content,String tips_url,int companyId,List<Integer> employeeIds) throws RemoteException;
}

//在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法 
try {
String RMIURL = "rmi://localhost:4321/";
IHello rhello = (IHello) Naming.lookup(RMIURL+"RHello");
System.out.println(rhello.helloWorld()); 
            System.out.println(rhello.sayHelloToSomeBody("远程调用")); 
            
            System.out.println("------------------------------------------");
            
            ISendMessage rSendMessage = (ISendMessage) Naming.lookup(RMIURL+"RSendMessage");

            List<Integer> employeeIds = new ArrayList();
            employeeIds.add(52789);
            employeeIds.add(52790);
            employeeIds.add(52791);
            
            com.partner.core.util.ResultVO result = rSendMessage.sendMessage("消息提醒", "待办提醒", "您有一个工作待办工作", "", 6,employeeIds );
            
            System.out.println("result:"+result.isRet()+" ,"+result.getMsg()+" ,"+result.getData());
            
            
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}



测试结果:

result:true ,正常 ,


0 0
原创粉丝点击