java RMI

RMI是什么?

RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。调用这样一个对象时,其参数为 "marshalled" 并将其从本地虚拟机发送到远程虚拟机(该远程虚拟机的参数为 "unmarshalled")上。该方法终止时,将编组来自远程机的结果并将结果发送到调用方的虚拟机。如果方法调用导致抛出异常,则该异常将指示给调用方。

 

RMI、Servlet、webservice区别

(摘自http://blog.csdn.net/linwei_1029/article/details/7033566

 

请求:   
  servlet:提供了请求/响应模式,是JAVA的一种规范,只能使用于java上,用来替代早期使用的难懂的CGI,是一种无状态的请求响应,客户端访问一个服务器的url,只需要发送简单的httprequest即可。 规定了四个范围:pageContext、request、session、application。一定依赖于各种SERVLET容器,但servlet只能接受一个简单的http请求;   
  WebService最早是微软提出了一种以XML为载体网络信息传输的规范,现在几乎所有的语言与平台都支持,带有状态机制,不依赖于SERVLET容器,可以发送一个xml作为其请求内容,WebService通常是基于http的远程方法调用(RMI),号称是可以反回远程对象, 一般来说客户段可以象调用本地方法一样调用WebService的方法。  
传输:   
  servlet使用http协议传输数据,如果你用Servlet返回XML,那个XML的描述框架就是你定的,必须告知使用者具体的说明,没有统一标准。   
  webservice使用固定的XML格式封装成soap消息,可以使用http作为底层数据传输,但并不局限于http协议,方法返回消息是有标准的。   
  返回结果:   
  servlet返回的是html页面;   
  webservice返回的可以是复杂对象甚至使用附件或者mutidata的二进制文件。   
  部署:   
  servlet需要遵守j2ee的Web   Application规范部署的应用服务器上,如tomcat,weblogic,websphere;   
  WebService则需要有WSDL文件来部署服务,或者使用UDDI注册。   
优势:   
  WebService的跨平台特性是servlet不能比的,可以被各种语言调用;   
  servlet相对来说速度上的优势也是不可忽视的。

  

 

  接下来在看看RMI和webservice中的 
  rmi的客户端和服务端都必须是java,webservice没有这个限制
  webservice是在http协议上传递xml文本文件,与语言和平台无关
  rmi是在tcp协议上传递可序列化的java对象,只能用在java虚拟机上,绑定语言
  RMI是EJB远程调用的基础,仅用RMI技术就可以实现远程调用,使用EJB是为了实现组件,事物,资源池,集群等功能。
  WebService是通过XML来传输数据,可用http等协议因此可在异构系统间传递,并且可以穿过防火墙,可在公网上远程调用

 

 

 

RMI对服务器的IP地址和端口依赖很紧密,但是在开发的时候不知道将来的服务器IP和端口如何,但是客户端程序依赖这个IP和端口。
这也是RMI的局限性之一。这个问题有两种解决途径:一是通过DNS来解决,二是通过封装将IP暴露到程序代码之外。
RMI的局限性之二是RMI是Java语言的远程调用,两端的程序语言必须是Java实现,对于不同语言间的通讯可以考虑用Web Service或者公用对象请求代理体系(CORBA)来实现

 

定义远程接口

 

import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * @Title: MyRemote.java 
 * @Description:定义远程调用接口
 * 定义一个接口必须继承java.rmi.Remote接口,内部定义方法必须抛出remoteException
 * 注:该接口必须进行Serializable否则会抛出java.io.NotSerializableException
 * @author xupan  
 * @Modified xupan      
 * @date 2013-6-14 上午9:03:25   
 * @version V1.0     
 */
public interface IMyRemote extends Remote ,Serializable{
	public String getMessage(String msg) throws RemoteException;
}
 实现远程接口内部方法
/**
 * @Title: MyTestRemote.java 
 * @Description: 远程接口实现 
 * @author xupan  
 * @Modified xupan      
 * @date 2013-6-14 上午9:08:16   
 * @version V1.0     
 */
public class MyRemoteImpl implements IMyRemote{

	private static final long serialVersionUID = 1L;

	public String getMessage(String msg) throws RemoteException {
		//获取当前虚拟机信息
		Properties properties=System.getProperties();
		System.out.println("当前虚拟机名称:"+properties.get("java.vm.name")+"客户端传来参数:"+msg);
		return msg;
	}

}
 注册接口到RMI注册表
/**
 * @Title: RemoteServer.java
 * @Description: 将远程对象注册到RMI注册表中启动RMI服务
 * @author xupan
 * @Modified xupan
 * @date 2013-6-14 上午9:25:56
 * @version V1.0
 */
public class RemoteServer {
	public static void main(String[] args) {
		// 创建一个远程对象
		IMyRemote remote = new MyRemoteImpl();
		try {
			// 本地主机上的远程对象注册表Registry的实例,并指定端口为10000,(Java默认端口是1099)
			LocateRegistry.createRegistry(10000);
			// 把远程对象注册到RMI注册服务器上
			Naming.bind("rmi://127.0.0.1:10000/MyRemote", remote);
			System.out.println("远程服务启动");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}


/**
 * @Title: RemoteClient.java
 * @Description: 调用远程对象
 * @author xupan
 * @Modified xupan
 * @date 2013-6-14 上午9:32:28
 * @version V1.0
 */
public class RemoteClient {
	public static void main(String[] args) {
		try {
			 //在RMI服务注册表中查找注册对象
			IMyRemote remote = (IMyRemote)Naming.lookup("rmi://127.0.0.1:8888/MyRemote");
			System.out.println(remote.getMessage("你好!"));
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (NotBoundException e) {
			e.printStackTrace();
		}
	}
}
 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值