服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

如何在java中用rmi来实现远程方法调用

一、java中的远程方法调用

远程方法调用(remote method invocation, rmi)是java1.1引入的分布式对象软件包,它的出现简化了在多台机器上的java应用之间的通信。相比corba,rmi功能较弱且只能用于java系统。

二、实现一个简单的rmi

要使用rmi,必须构造四个主要的类:远程对象的本地接口、rmi客户、远程对象实现和rmi服务器。rmi服务器生成远程对象实现的一个实例,并用一个特殊的url注册它,rmi客户在远程服务器上查找对象,若找到就把它转换成本地接口类型,然后像一个本地对象一样使用它。下面是一个简单的rmi例子,远程对象只返回一个消息字符串。要使这个例子更有价值,我们需要做的就是完善远程对象实现类。

1.远程对象的本地接口类(rem.java)

该类仅仅是一个接口,而不是实现,rmi客户机可以直接使用它,rmi服务器必须通过一个远程对象来实现它,并用某个url注册它的一个实例。

import java.rmi.*;
public interface rem extends remote { public string getmessage() throws remoteexception;}

本地接口(rem)必须是公共的,否则客户机在加载一个实现该接口的远程对象时就会出错。此外,它还必须从java.rmi.remote继承而来,接口中的每一个方法都必须抛出远程异常java.rmi.remoteexception。

2.rmi客户类(remclient.java)

rmi客户使用naming.lookup在指定的远程主机上查找对象,若找到就把它转换成本地接口rem类型,然后像一个本地对象一样使用它。与corba不同之处在于rmi客户必须知道提供远程服务主机的url,这个url可以通过rmi://host/path或rmi://host:port/path来指定,如果省略端口号,就使用1099。naming.lookup可能产生三个异常:remoteexception、notboundexception、malformedurlexception,三个寻常都需要捕获。remoteexception、naming和notboundexception在java.rmi.*中定义,malformedurlexception在java.net.*中定义。另外,客户机将向远程对象传递串行化对象serializable,所以还应在程序中输入java.io.*。

import java.rmi.*;
import java.net.*;
import java.io.*;
public class remclient {
public static void main(string[] args) {
try {
//从命令行读取远程主机名
string host = (args.length > 0) ? args[0] : "localhost";
//通过url在远程主机上查找对象,并把它转化为本地接口rem类型
rem remobject=(rem)naming.lookup("rmi://" + host + "/rem");
system.out.println(remobject.getmessage()); //调用远程对象的方法
} catch(remoteexception re) {
system.out.println("remoteexception: " + re);
} catch(notboundexception nbe) {s
ystem.out.println("notboundexception: " + nbe);
} catch(malformedurlexception mfe){
system.out.println("malformedurlexception:"+ mfe);
}}}

3.远程对象实现类(remimpl.java)

这个类真正实现rmi客户调用的远程对象,它必须从unicastremoteobject继承,其构造函数应抛出remoteexception异常。

import java.rmi.*;
import java.rmi.server.unicastremoteobject
public class remimpl extends unicastremoteobject implements rem {
public remimpl() throws remoteexception {} //构造函数抛出remoteexception异常
public string getmessage() throws remoteexception {
return("here is a remote message."); }} //向rmi客户返回一个消息串

4.rmi服务器类(remserver.java)该类创建远程对象实现remimpl的一个实例,然后用一个特定的url来注册它,所谓注册就是通过naming.bind或naming.rebind来将remimpl实例绑定到url上。

import java.rmi.*;
import java.net.*; 
public class remserver {
public static void main(string[] args) {
 try { 
 remimpl localobject = new remimpl(); //生成远程对象实现的一个实例 
 naming.rebind("rmi:///rem", localobject); //将远程对象实例绑定到rmi:///rem上
 }catch(remoteexception re){
system.out.println("remoteexception:"+re); 
}catch(malformedurlexception mfe) {
system.out.println("malformedurlexception: "+mfe);
 }}}

三、编译和运行

编译rmi客户和服务器,这将自动编译远程对象的本地接口和远程对象实现

javac remclient.java //自动编译远程对象的本地接口rem.java

javac remserver.java //自动编译远程对象实现remimpl.java

生成客户承接模块和服务器框架

rmic remimpl

这将构造remimpl_stub.class和remimpl_skeleton.class。请将rem.class、remclient.class和remimpl_stub.class拷贝到rmi客户机,将rem.class、remimpl.class 、remserver.class和remimpl_skeleton.class拷贝到rmi服务器。

启动rmi注册

rmiregistry

//在服务器上执行。不论有多少个远程对象,本操作只需做一次

运行java remserver.class

//启动rmi服务器(在服务器上执行)

java remclient.class

//启动rmi客户,将输出“here is a remote message.”

扫描关注微信公众号