javaEE之远程方法调用(RMI)

命令行中运行

RMI是一种分布式应用程序开发方法,采用该方法客户端可调用服务器端的远程对象,就像调用客户端自身方法一样。

使用RMI远程调用需要服务器、客户端、客户端辅助设备(Stub)、服务器辅助设备(skeleton)。

在远程方法调用过程中,客户端看起来像是直接调用远程的方法,其实是辅助设备假装成服务对象(但并不是真正的远程服务),由辅助设备去连接服务器,将调用的方法和参数通过socket传递到服务的辅助设备(Skeleton),然后调用真正的服务。



实现一个RMI程序通常要完成以下几个步骤:

(1)创建远程接口定义客户端和远程调用的方法(继承Remote)

(2)创建远程接口实现类并完成服务器端程序编写,这时客户端会调用的对象。

(3)调用rmic命令生成stub和skeleton(现在已经不生成skeleton)

(4)使用rmregistry命令生成RMI注册表(也可在程序中使用LocateRegistry.createRegistry(1099)指定,这样就不需使用命令启动注册表)

(5)运行服务器和客户端程序


下面是一个简单的RMI程序:

MyRemote接口:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface MyRemote extends Remote {

	public String sayHello() throws RemoteException;
}


MyRemoteImpl接口实现类(提供远程服务):

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;

public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {

	protected MyRemoteImpl() throws RemoteException {
	}

	
	public String sayHello() {
		return "Hello";
	}

	//创建远程对象,使用rebind产生关联,注册名称供客户端查询
	public static void main(String[] args) {

		
		try {
			MyRemote service = new MyRemoteImpl();
			LocateRegistry.createRegistry(1099);
			Naming.rebind("rmi://localhost:1099/Hello", service);
			
			System.out.println("Ready...");
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


客户端程序:

import java.rmi.Naming;

//为什么在ide编写在dos下编译不通过?
public class MyRemoteClient {

	public static void main(String[] args) {
		
		try {
			MyRemote service = (MyRemote) Naming.lookup("rmi://localhost:1099/Hello");
			String str = service.sayHello();
			
			System.out.println(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

几点需要注意:

1、远程接口继承Remote接口且所有方法必须声明RemoteException(需通过socket传递)

2、远程服务应该继承UnicastRemoteObject(最简单的创建远程对象的方式)

3、远程服务构造方法声明RemoteException异常,因为父类的构造函数声明了异常

4、可通过rmiregistry或在程序中实现启动RMI注册表(通常采用在程序中的方法,上面的程序使用命令启动出现classnotfound错误,原因不明(rmiregistry命令已在stub.class所在目录启动))


在eclipse中使用RMI插件运行

在eclipse中从可 http://www.genady.net/rmi/v20/在线安装rmi插件,在工程上右键rmi->enable stubs genreation生成_stub.class 类文件,再点击RMI plugin图标启动registry。
然后 配置运行RMI服务,右键点击左边树中的MyRemoteImpl.java文件,菜单run as->rmi application,在弹出对话框中找到RMI VM Properties.选中java.security.polcy的value框,点击按钮会出现文件选择对话框,我们这里采用自动生成的security.policy文件(加载动态类的RMI应用需要配置.policy文件),同理,java.rmi.server.codebase也采用生成的服务器的地址(codebase是配置_stub.class文件在bin目录下。client端调用远程对象解序列化要求要有stub类,设置codebase是使用动态类下载时告知调用远程对象时寻找该对象类文件的URL标记的方法。注册远程对象的一端需要制定codebase,调用远程对象需要指定codebase即是注册远程对象制定的codebase)。设置过后,就将服务器程序运行起来。
配置客户端程序的java.security.polcy的value使用服务器端生成的.policy文件的地址,codebaseURL地址也使用服务器端生成文件的地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值