基于RMI技术的远程词典应用
一、场景描述:
假设有一台应用服务器以RMI(或Socket编程)的方式向客户端提供英汉互译词典的服务。请尝试完成服务器端程序编码和一个客户端应用,并分别部署到两台计算机上进行测试。说明:不考虑服务器端词典的容量,用数据库或使用Map在内存中保存少量的英汉词汇对应表。
二、相关代码:
1. 远程接口定义
远程词典接口定义如下代码所示,定义了一个翻译函数translate。
package com.dic;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* @author cz
*
*/
public interface Translator extends Remote {
/**
*
* @param str 需要被翻译的单词
* @return 英汉互译后的内容,如果词典中不包含此单词返回null
* @throws RemoteException
*/
public String translate(String str) throws RemoteException;
}
2. 服务器端实现
对远程词典接口的一个具体实现,同时继承了RMI的UnicastRemoteObject类。主要是实现了translate函数,在本次实验中,由于不考虑服务器端词典的容量,仅适用Map构造了一个字典来存储少量的英汉词汇对应表。然后是为了测试,将实现的TranslatorImpl类使用RMI的命名空间绑定服务器的地址(这里使用的是本机测试地址),以便于客户端实现远程调用。
package com.dic;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
/**
* @author cz
*
*/
public class TranslatorImpl extends UnicastRemoteObject implements Translator {
/**
*
*/
private static final long serialVersionUID = 1L;
private Map dict = new HashMap();
protected TranslatorImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
@Override
public String translate(String str) throws RemoteException {
dict.put("分布式", "distributed");
dict.put("系统", "system");
dict.put("distributed", "分布式");
dict.put("system", "系统");
return dict.get(str).toString();
}
public static void main(String[] args) {
System.setSecurityManager(new RMISecurityManager());
try {
TranslatorImpl tran = new TranslatorImpl();
Naming.rebind("//127.0.0.1/TranslatorImpl", tran);
System.out.println("词典服务器端已启动!");
} catch(Exception e) {
e.printStackTrace();
}
}
}
3. 客户端实现
客户端的实现在一个SearchDictionary类中定义,首先使用RMI的命名空间找到服务器端定义的服务TranslatorImpl,然后输入要翻译的单词,便自动调用服务器端的词典功能,给出翻译结果。
package com.dic;
import java.rmi.*;
import java.util.Scanner;
//import com.server.Translator;
/**
* @author cz
*
*/
public class SearchDictionary {
/**
* @param args
*/
@SuppressWarnings("deprecation")
public static void main(String[] args) {
System.setSecurityManager(new RMISecurityManager());
try {
Translator tran = (Translator)Naming.lookup("//127.0.0.1/TranslatorImpl");
Scanner sc = new Scanner(System.in);
System.out.println("请输入要翻译词语");
String word = sc.nextLine();
System.out.println(word + "的意思是" + tran.translate(word));
} catch(Exception e) {
e.printStackTrace();
}
}
}
4. 创建policy文件
定义一个安全管理器配置文件,给定所有权限。
grant{
permission java.security.AllPermission "","";
};
三、实验运行结果:
1. 服务器端和客户端编译
服务器端(命令行):
javac –classpath . -d . Translator.java
javac –classpath . -d . TranslatorImpl.java
客户端(命令行):
javac –classpath . -d . SearchDictionary.java
2. 启动RMI Registry服务(命令行)
start rmiregistry
RMI注册服务启动成功后为下图所示界面,这样就能够创建注册表,在注册表中存储远程对象信息。
3. 启动服务器端程序(命令行)
Java –Djava.security.policy=policy.txt –classpath . com.dic.TranslatorImpl
服务器端启动成功后如下图所示
4. 运行客户端程序
Java –Djava.security.policy=policy.txt –classpath . com.dic.SearchDictionary
服务器端运行界面如下
四、实验总结
通过本次实验,简单实现了基于RMI的远程词典应用,是的自己对RMI技术的运行机制有了更深一步的理解。同时在代码的过程中了解到在使用Java进行RMI远程调用中所需要注意的一些问题。最后,感谢老师的课堂指导以及给我们这次的实验机会,让我在学习知识的同时又提高了自己的代码能力!