RMI(远程方法调用)实现简单的查单词功能

本文介绍了Java的RMI(远程方法调用)技术,用于开发分布式应用程序。RMI通过存根和框架使得远程对象在不同操作系统间通信变得可能。文中以一个简单的英译汉词典服务为例,详细阐述了如何实现RMI,包括创建远程接口、服务器类和客户端类,最终在两个不同机器上分别运行服务器端和客户端并展示运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. RMI概念

        RMI(Remote Method Invocation),远程方法调用,是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。简单地说,这样使原先的程序在同一操作系统的方法调用,变成了不同操作系统之间程序的方法调用,由于J2EE是分布式程序平台,它以RMI机制实现程序组件在不同操作系统之间的通信。比如,一个EJB可以通过RMI调用Web上另一台机器上的EJB远程方法。

2. 工作原理

        在RMI中,调用远程对象的对象被称为客户机对象(Client   Object)而远程对象被称为服务器对象(Server   Object),同时引入了两种特殊类型对象,存根(stub)和框架(Skelton)。存根实际上是远程对象的客户端代理,它和远程对象具有相同的接口或方法列表,当客户端调用远程对象时,实际上是由相应的存根对象代理完成。在服务器端,框架对象处理“远方”的所有细节,完全可以像编写本地对象一样来编写远程对象。框架将远程对象从RMI基础结构分离开来。也就是说,客户端获得的只是代理对象,并不是服务器上的类型,只不过它实现了服务器上类型的全部功能。

3. 实例

实现简单的查单词功能,一台应用服务器以RMI的方式向客户端提供英译汉词典的服务。

创建一个简单的Java分布式远程方法调用程序可以按以下几个步骤操作:

1)定义远程接口

/**
 * 功能说明:定义一个远程接口,必须继承Remote接口,其中需要远程调用的方法必须抛出RemoteException异常 
 * 作者: gangwazi
 * 创建时间:2012-6-27
 */
public interface WordTranslate extends Remote {
	/**
	 * @param str 需要被翻译的单词
	 * @return 英汉互译后的内容,如果词典中不包含此单词返回null
	 */
	public String translate(String str) throws RemoteException;
}

2)实现远程接口

/**
 * 功能说明:远程接口的实现
 * 作者: gangwazi
 * 创建时间:2012-6-27
 */
public class WordTranslateImpl extends UnicastRemoteObject implements WordTranslate {

	private static final long serialVersionUID = 1L;
	public Map<String, String> wordMap = new HashMap<String, String>();

	// 因为UnicastRemoteObject的构造方法抛出了RemoteException异常,因此这里默认的构造方法必须写,必须声明抛出RemoteException异常 
	public WordTranslateImpl() throws RemoteException {
		super();
		wordMap.put("China", "n. 中国");
		wordMap.put("Japan", "n. 日本");
		wordMap.put("German", "德国");
		wordMap.put("list", "n. 列表; v. 列出");
		wordMap.put("egg", "n. 鸡蛋");
		wordMap.put("map", "n. 地图");
		wordMap.put("translate", "v. 翻译");
		wordMap.put("banana", "n. 香蕉");
		wordMap.put("apple", "n. 苹果");
		wordMap.put("orange", "n. 橘子");
		wordMap.put("milk", "n. 牛奶");
		wordMap.put("water", "n. 水");
		wordMap.put("drink", "v. 喝,饮");
	}

	@Override
	public String translate(String str) throws RemoteException {
		if (wordMap.containsKey(str)) {
			return wordMap.get(str);
		} else {
			return null;
		}
	}

}
由于只是简单的示例,故词典使用map来存储,当然也可以构造专门的词典文件或者从数据库中查询。

3)编写服务器类

/**
 * 功能说明:创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。 
 * 作者: gangwazi
 * 创建时间:2012-6-27
 */
public class WordTranslateServer {

	public static void main(String[] args) {
		try {
			// 创建一个远程对象
			WordTranslate rTranslate = new WordTranslateImpl();
			// 本地主机上的远程对象注册表Registry的实例,并指定端口为5555,这一步必不可少(Java默认端口是1099),
			// 必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上 
            LocateRegistry.createRegistry(5555);
            // 把远程对象注册到RMI注册服务器上,并命名为RTranslate
            // 绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略)
            Naming.bind("rmi://localhost:5555/RTranslate", rTranslate);
            System.out.println(">>>>>INFO: 远程WorldTranslate对象绑定成功!");
		} catch (RemoteException e) {
			System.out.println("创建远程对象发生异常!");
			e.printStackTrace();
		} catch (MalformedURLException e) {
			System.out.println("发生URL畸形异常!");
			e.printStackTrace();
		} catch (AlreadyBoundException e) {
			System.out.println("发生重复绑定对象异常!");
			e.printStackTrace();
		}
	}
}

4)编写客户端类

/**
 * 功能说明:客户端测试,在客户端调用远程对象上的远程方法,并返回结果。
 * 作者: gangwazi
 * 创建时间:2012-6-27
 */
public class WorldTranslateClient {

	public static void main(String[] args) {
		try {
			// 在RMI服务注册表中查找名称为RTranslate的对象,并调用其上的方法 
			WordTranslate rTranslate = (WordTranslate) Naming.lookup("rmi://202.117.10.64:5555/RTranslate");
			System.out.print("查询单词 China----------->");
			System.out.println(rTranslate.translate("China"));
			System.out.print("查询单词 list----------->");
			System.out.println(rTranslate.translate("list"));
			System.out.print("查询单词 present----------->");
			System.out.println(rTranslate.translate("present"));
			System.out.print("查询单词 banana----------->");
			System.out.println(rTranslate.translate("banana"));
			System.out.print("查询单词 util----------->");
			System.out.println(rTranslate.translate("util"));
			System.out.print("查询单词 drink----------->");
			System.out.println(rTranslate.translate("drink"));
		} 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();
		}
	}
}

4. 运行结果

服务器端和客户端分别运行在两台机子上

服务器端运行结果


客户端运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值