`

一个RMI初学者写的小程序

    博客分类:
  • j2ee
阅读更多
说明:程序由7个文件组成
请将这7个文件放在d:\rmi目录下面,
然后用记事本打开compile and run.bat, 运行cmd, 逐条执行里面的命令,(若直接点击则不会启动客户端)

================================================
IServer.java RMI 远程服务接口
ServerImpl.java RMI 远程服务实现类
Client.java RMI 本地客户端
RmiUtil.java RMI 工具类
config.properties RMI配置参数
my.policy RMI安全授权
compile and run.bat cmd编译和运行命令
================================================


IServer.java :

package rmi;

/**
 * RMI 远程服务接口
 * 
 * @author mail@shadowsnow.com
 * @since 1.6
 * @version %I%, %G%
 */
public interface IServer extends java.rmi.Remote {

	/**
	 * 响应反馈字符串
	 * 
	 * @param num 反馈字符串重复的次数
	 * @return 反馈字符串
	 */
	public String response(int num) throws java.rmi.RemoteException;

	/**
	 * 动态调用方法
	 * 
	 * @param method 要调用的方法名(空参)
	 * @return 反馈字符串
	 */
	public String request(String method) throws java.rmi.RemoteException;

}




ServerImpl.java :

package rmi;

import java.lang.reflect.Method;
import java.net.URL;
import java.util.Map;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.RMIClassLoader;
import java.rmi.registry.*;
import rmi.RmiUtil;

/**
 * RMI 远程服务实现类
 * 
 * @author mail@shadowsnow.com
 * @since 1.6
 * @version %I%, %G%
 */
public class ServerImpl extends UnicastRemoteObject implements IServer {
	
	/**
	 * 版本序列号
	 */
	public static final long serialVersionUID = 1L;

	/**
	 * 无参的构造方法
	 */
	public ServerImpl() throws java.rmi.RemoteException {
		super();
	}

	/**
	 * 响应反馈字符串
	 * 
	 * @param num 反馈字符串重复的次数
	 * @return 反馈字符串
	 */
	public String response(int num) throws RemoteException {
		// 获取配置参数
		Map<String, String> map = RmiUtil.getConfig();
		String response = "";
		for (int i = 0; i < num; i++) {
			response += "[" + (i + 1) + "]" + map.get("response") + "\n";
		}

		return response;
	}

	/**
	 * 动态调用方法
	 * 
	 * @param method 要调用的方法名(空参)
	 * @return 反馈字符串
	 */
	public String request(String method) throws RemoteException {

		try {

			// 获取class
			// Class<?> c = Class.forName("rmi.ServerImpl");
			Class<?> c = this.getClass();
			// 获取method指定的方法
			Method m = c.getMethod(method);
			// 获取所有 定义了的方法
			Method ms[] = c.getDeclaredMethods();
			System.out.println("\nThe methods of rmi.ServerImpl :\n ");
			for (int i = 0; i < ms.length; i++) {
				System.out.println(ms[i].toString());
			}
			// 动态执行方法
			// return (String) m.invoke(c.newInstance());
			return (String) m.invoke(this);

		} catch (Exception e) {
			e.printStackTrace();
			return "Error: Cannot Invoke The Method: " + method;
		}

	}

	/**
	 * 响应反馈字符串
	 * 
	 * @return 反馈字符串
	 */
	public String feedback() throws RemoteException {
		// 获取配置参数
		Map<String, String> map = RmiUtil.getConfig();		
		
		try {
			// 远程类的字节码codebase
			URL base=new URL("http://" + map.get("host") + "/");
			// 远程类的全限定名称
			String name = "rmi.Client";
			// RMI 进行动态类加载
			RMIClassLoader.loadClass(base,name); 
			// 加载远程类字节码后调用函数
			Client.remoteCall();
			
		} catch (Exception e) {
			e.printStackTrace();
		}	
		
		return map.get("request");
	}

	/**
	 * 主函数
	 * 
	 * @param args 主函数参数
	 */
	public static void main(String[] args) {
		// 设置RMI的安全策略
		RmiUtil.setSecurityManager();
		try {
			// 获取配置参数
			Map<String, String> map = RmiUtil.getConfig();
			// RMI服务对象
			ServerImpl obj = new ServerImpl();
			// 注册端口,并返回Registry对象
			Registry reg = RmiUtil.createRegistry(
				Integer.parseInt(map.get("port"))
			);
			// 绑定服务对象
			RmiUtil.rebind(reg, map.get("name"), obj);
			System.out.println("RmiServer Running...");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}





Client.java:

package rmi;

import rmi.RmiUtil;
import java.util.Map;

/**
 * RMI 本地客户端
 * 
 * @author mail@shadowsnow.com
 * @since 1.6
 * @version %I%, %G%
 */
public class Client {

	/**
	 * 加载远程类字节码后调用函数
	 */
	public static void remoteCall(){
		System.out.println("Remote Calling...");		
	} 
	
	/**
	 * 主函数
	 * 
	 * @param args 主函数参数
	 */
	public static void main(String args[]) {
		// 设置rmi安全策略
		RmiUtil.setSecurityManager();
		try {
			// 获取配置参数
			Map<String, String> map = RmiUtil.getConfig();
			// rmi服务主机名
			String host = map.get("host");
			// rmi服务端口
			String port = map.get("port");
			// rmi服务名
			String name = map.get("name");
			// 反馈字符串重复的次数
			int num = Integer.parseInt(map.get("num"));
			// 要动态调用的方法名
			String method = map.get("method");
			// rmi服务url地址
			String url = "rmi://" + host + ":" + port + "/" + name;
			// 通过RMI服务url地址,获取RMI服务对象
			IServer obj = (IServer) RmiUtil.lookup(url);
			// 响应反馈字符串,重复num次
			String response = obj.response(num);
			// 动态调用method方法
			String request = obj.request(method);

			System.out.println("RmiClient Running...");
			System.out.println("url: " + url);
			System.out.println(response);
			System.out.println(request);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}






RmiUtil.java :

package rmi;

import java.rmi.*;
import java.util.Map;
import java.util.HashMap;
import java.rmi.registry.*;
import java.io.*;
import java.util.Properties;

/**
 * RMI 工具类
 * 
 * @author mail@shadowsnow.com
 * @since 1.6
 * @version %I%, %G%
 */
public final class RmiUtil {

	/**
	 * 是否第一次打印出配置参数
	 * <p>
	 * <code>true</code> 第一次打印<br>
	 * <code>false</code> 非第一次打印(略过打印)<br>
	 */
	public static boolean isFirstPrint = false;

	/**
	 * 注册RMI端口,并返回Registr对象
	 * 
	 * @param port RMI端口
	 * @return Registr对象
	 */
	public static Registry createRegistry(int port) throws RemoteException {
		Registry reg = null;
		try {
			// 如果该端口未被注册,则抛异常
			reg = LocateRegistry.getRegistry(port);
			// 获取该端口注册的rmi对象
			reg.list();
		} catch (RemoteException e) {
			try {
				// 捕获异常,端口注册
				reg = LocateRegistry.createRegistry(port);
			} catch (RemoteException e2) {
				e2.printStackTrace();
			}
		}

		return reg;

	}

	/**
	 * 通过Registry对象, 绑定RMI服务
	 * 
	 * @param reg Registry对象
	 * @param name RMI服务名
	 * @param obj RMI服务对象
	 */
	public static void rebind(Registry reg, String name, Remote obj)
			throws Exception {
		try {
			reg.rebind(name, obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 直接通过Naming绑定RMI服务
	 * 
	 * @param name RMI服务名
	 * @param obj RMI服务对象
	 */
	public static void rebind(String name, Remote obj) throws Exception {
		try {
			Naming.rebind(name, obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 通过RMI服务url地址,获取RMI服务对象
	 * 
	 * @param url RMI服务url地址
	 * @return RMI服务对象
	 */
	public static Remote lookup(String url) throws Exception {

		try {
			return Naming.lookup(url);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 配置RMI安全策略
	 */
	public static void setSecurityManager() {
		System.setSecurityManager(new RMISecurityManager());
	}

	/**
	 * 从config.properties获取配置参数
	 * 
	 * @return 配置参数
	 */
	public static Map<String, String> getConfig() {

		Map<String, String> map = null;

		try {
			// RmiUtil类的上级目录的绝对地址
			String path = RmiUtil.class.getResource("").toString();
			// config.properties的绝对地址
			path += "config.properties";
			// windows下去掉file:/
			path = path.replace("file:/", "");
			// windows下将/替换为\
			path = path.replace("/", "\\");
			// 拿到config.properties的InputStream
			InputStream in = new BufferedInputStream(new FileInputStream(path));
			Properties p = new Properties();
			// 读取config.properties内容
			p.load(in);

			// 读取config.properties的显示字符集
			String encode = p.getProperty("encode");
			map = new HashMap<String, String>();
			// 逐个将配置参数转换为指定的字符集
			map.put("encode", new String(
				p.getProperty("encode").getBytes("ISO8859-1"), encode)
			);
			map.put("name", new String(
				p.getProperty("name").getBytes("ISO8859-1"), encode)
			);
			map.put("host", new String(
				p.getProperty("host").getBytes("ISO8859-1"), encode)
			);
			map.put("port", new String(
				p.getProperty("port").getBytes("ISO8859-1"), encode)
			);
			map.put("response", new String(
				p.getProperty("response").getBytes("ISO8859-1"), encode)
			);
			map.put("request", new String(
				p.getProperty("request").getBytes("ISO8859-1"), encode)
			);
			map.put("num", new String(
				p.getProperty("num").getBytes("ISO8859-1"), encode)
			);
			map.put("method", new String(
				p.getProperty("method").getBytes("ISO8859-1"), encode)
			);

			// 只有在第一次调用才打印配置参数
			if (!isFirstPrint) {
				isFirstPrint = true;
				System.out.println();
				System.out.println("============= config datas start ================");
				System.out.println("config path: " + path);
				System.out.println("encode: " + map.get("encode"));
				System.out.println("name: " + map.get("name"));
				System.out.println("host: " + map.get("host"));
				System.out.println("port: " + map.get("port"));
				System.out.println("response: " + map.get("response"));
				System.out.println("request: " + map.get("request"));
				System.out.println("num: " + map.get("num"));
				System.out.println("method: " + map.get("method"));
				System.out.println("============= config datas end ================");
				System.out.println();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

		return map;

	}

}





config.properties:

# RMI配置参数

# 配置文件的显示字符集
encode=gbk

# 远程RMI绑定的服务名
name=RmiServer

# 远程RMI的主机名
host=localhost

# 远程RMI的端口
port=8765

# 反馈字符串1
response=你好,rmi反馈成功

# 反馈字符串2
request=方法调用成功

# 反馈字符串重复的次数
num=10

# 要动态调用的方法名
method=feedback




my.policy :

grant{
	permission java.security.AllPermission;
};


compile and run.bat :


d:
cd d:\
cd rmi
java -d .. *.java
cd ../
rmic -d . rmi.ServerImpl

start rmiregistry
java -Djava.security.policy=d:\rmi\my.policy rmi.ServerImpl
java -Djava.security.policy=d:\rmi\my.policy rmi.Client


0
2
分享到:
评论
2 楼 skanion 2011-09-09  
高手们请多多指教
1 楼 skanion 2011-09-09  
沙发

相关推荐

    rmi服务端与客户端小程序

    本项目"rmi服务端与客户端小程序"提供了简单易懂的示例,帮助初学者快速理解和上手RMI。 1. **RMI基本概念** - **远程对象**:在远程JVM上运行的对象,可以通过RMI接口被本地对象调用。 - **接口**:定义了远程...

    RMI.rar_DEMO_rmi

    在这个“RMI.rar_DEMO_rmi”压缩包中,包含了一个RMI的示例项目,对于初学者或者想要深入理解中间件技术的人来说是一个很好的学习资源。 首先,我们来了解RMI的基本概念。RMI的核心思想是,一个Java对象可以在本地...

    RMI入门小结

    总的来说,“RMI入门小结”这篇博客对初学者理解RMI的概念、工作原理以及如何使用RMI进行分布式编程具有很好的指导作用。通过学习RMI,开发者能够构建更复杂的分布式Java应用程序,实现远程对象间的交互。同时,对...

    RMI使用学习 小结

    ### RMI使用学习小结 #### 一、RMI简介及应用场景 ...对于初学者而言,掌握RMI的基本原理和实现方法是非常有益的,有助于理解分布式系统的构建原理。而对于实际工程项目,应根据具体需求选择最适合的技术栈。

    jndi测试小项目,初学者

    1. **初始化Naming Context**:应用程序首先需要创建一个初始的Naming Context,这通常通过`InitialContext()`构造函数完成。 2. **查找资源**:使用`lookup()`方法,传入资源的逻辑名称,JNDI会递归地在命名树中...

    Java初学者入门教学

    2.7 我们的第一个Java程序 2.8 注释和嵌入文档 2.8.1 注释文档 2.8.2 具体语法 2.8.3 嵌入HTML 2.8.4 @see:引用其他类 2.8.5 类文档标记 2.8.6 变量文档标记 2.8.7 方法文档标记 2.8.8 文档示例 2.9 编码样式 2.10 ...

    Java基础教程(经典)【适合初学者阅读】借鉴.pdf

    对于初学者来说,选择一个好的教程至关重要。好的Java教程应该深入浅出,易于理解,能够帮助学习者建立起扎实的基础,理解编程思维,而不只是传授表面的知识点。随着Java技术的不断发展,保持教程的时效性也是关键,...

    Java基础教程【适合初学者阅读】编程资料

    - **Java RMI (Remote Method Invocation)**: 远程方法调用,用于不同JVM间的通信。 - **JavaBeans**: 规范化组件开发的标准。 - **Java OS**: 基于Java的轻量级操作系统。 - **Java Servlet**: Web服务器端的技术,...

    北大JAVA讲义

    第二章“Java小程序”可能涉及Java Applet,这是一种能够在网页中运行的小型Java程序,虽然现在Applet的使用已经减少,但它对于理解Java与Web的结合很有帮助。 第三章“Java事件”讲解了GUI组件上的事件处理,如...

    配套课件-Java程序设计简明教程.ppt

    总之,Java程序设计简明教程涵盖了Java的历史、版本、与C/C++的区别、语言特点以及程序类型等方面的基础知识,对于初学者来说是很好的学习资源。通过深入理解和实践这些概念,开发者能够掌握Java编程的核心,并利用...

    火车票售票系统(网络版)

    对于初学者来说,这个项目提供了一个实际运用Java RMI的机会,同时也能锻炼到数据库操作、网络编程和用户界面设计等多方面的技能。虽然开发者谦虚地称其为"小菜菜",但这样的实践经历对于理解分布式系统和提升编程...

    java编写井字棋网络版小游戏

    井字棋网络版小游戏是基于Java编程语言开发的一款简单但有趣的多人在线对战游戏。它利用TCP(Transmission Control Protocol)...这个项目不仅可以帮助初学者熟悉Java编程,还能提升他们对于网络编程和游戏开发的理解。

    北京大学Java课件

    北京大学的Java课件是一系列深入学习Java编程语言的...这些课件全面讲解了Java编程的各个方面,无论你是初学者还是希望巩固知识的开发者,都能从中受益。通过学习,你将能够熟练掌握Java编程,为软件开发打下坚实基础。

    Java云计算简单示例

    这个"Java云计算简单示例"可能是为了介绍如何使用Java编程语言来实现基本的云计算功能,尽管它可能不是最新或最先进的技术,但对于初学者来说,这是一个很好的起点,能够帮助他们理解基础概念。 首先,我们要了解...

    Java讲义

    接着,“第2章 Java小应用”可能涉及编写简单的Java程序,如控制台应用程序,帮助初学者快速体验编程的乐趣和实用性。这一章通常会介绍基本的输入输出操作,以及流程控制语句(如if语句、for循环和while循环)。 ...

    An Introduction to Network Programming with Java

    远程方法调用(Remote Method Invocation, RMI)是Java平台提供的一个重要的分布式计算技术。通过RMI,可以在不同的虚拟机(JVM)之间透明地调用远程对象的方法,就像调用本地对象一样。这一章将详细介绍RMI的工作原理、...

    java学习方向[参考].pdf

    Java学习之路是一个逐步深入的过程,尤其对于初学者来说,了解并掌握正确的学习方向至关重要。本文将探讨Java的不同版本,以及如何有效地学习Java,特别是针对J2SE和J2EE的知识点。 首先,J2ME(Java 2 Platform, ...

    java_北京大学讲义

    Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据着重要地位。北京大学的这份“java_北京大学讲义”提供了全面的Java学习资源,涵盖了从基础...对于有志于Java开发的初学者,这是一个极好的自学资源。

Global site tag (gtag.js) - Google Analytics