RMI远程方法调用

来源:互联网 发布:供销大数据集团多少人 编辑:程序博客网 时间:2024/05/21 15:46

 

RMI(即Remote Method Invoke 远程方法调用)。在Java中,只要一个类extends了java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定的服务

以下内容是参考java  API文档和自己实地代码测试的结果!!!

写接口

接口均要继承java.rmi. Remote接口。

Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口。任何远程对象都必须直接或间接实现此接口。只有在“远程接口”(扩展 java.rmi.Remote 的接口)中指定的这些方法才可远程使用。

实现类可以实现任意数量的远程接口,并且可以扩展其他远程实现类。RMI 提供一些远程对象实现可以扩展的有用类,这些类便于远程对象创建。这些类是java.rmi.server.UnicastRemoteObjectjava.rmi.activation.Activatable

注意:extends了Remote接口的类或者其他接口中的方法必须要声明抛出RemoteException异常,该才方法可被客户端远程访问调用。

 例:

import java.rmi.Remote;

importjava.rmi.RemoteException;

publicinterface IRemoteServiceextends Remote{

String extract(String str)throws RemoteException;

}

写实现类

实现类除了要实现自定义的接口还要java.rmi.server.UniCastRemoteObject类(这是必须的)。因为这样才能保证客户端访问获得远程对象时,该远程对象将会把自身的一个拷贝以Socket的形式传输给客户端,此时客户端所获得的这个拷贝称为“存根”,而服务器端本身已存在的远程对象则称之为“骨架”。其实此时的存根是客户端的一个代理,用于与服务器端的通信,而骨架也可认为是服务器端的一个代理,用于接收客户端的请求之后调用远程方法来响应客户端的请求。

例:

importjava.rmi.RemoteException;

importjava.rmi.server.UnicastRemoteObject;

publicclass RemoteServiceIml

extends UnicastRemoteObject

implements IRemoteService{

   protected RemoteServiceIml()throws RemoteException {

      super();

   }

   @Override

   public String extract(String filePath) {

      System.err.println("extract执行了"); 

      return"extract方法返回";

}

} 

实现类方法可抛异常也可不抛

写服务端

java.rmi.registry. Registry是简单远程对象注册表的一个远程接口,它提供存储和获取绑定了任意字符串名称的远程对象引用的方法。bindunbindrebind 方法用于改变注册表中的名称绑定,lookuplist方法用于查询当前的名称绑定。

在其典型用法中,Registry 启用 RMI 客户机引导:它为客户机提供获得对远程对象的初始引用的简单方式。因此,导出的注册表的远程对象实现通常具有已知的地址,如具有已知的ObjID 和 TCP 端口号(默认为1099)。

Registry 实现可以选择限制对其中的某些或全部方法的访问(例如,可以限制改变注册表绑定的方法来限制对本地主机发起的调用)。如果Registry 方法选择拒绝对给定调用的访问,则其实现可能抛出AccessException,抛出的这一异常(因为它扩展RemoteException)可能会在远程客户端捕获它时包装在ServerException 中。

Registry 中用于绑定的名称是纯字符串,不是经过分析的。在Registry 中存储其远程引用的服务可能希望将包名称用作名称绑定中的前缀,以减少注册表中可能的名称冲突。

       方法摘要

 void

bind(String name,Remote obj) 绑定对此注册表中指定 name 的远程引用。

 String[]

list() 返回在此注册表中绑定的名称的数组。

 Remote

lookup(String name)
返回注册表中绑定到指定 name 的远程引用。

 void

rebind(String name,Remote obj)
用提供的远程引用替换此注册表中指定的 name 绑定。

 void

unbind(String name)
移除此注册表中指定的 name 绑定。

 

java.rmi.registry. LocateRegistry用于获得对特定主机(包括本地主机)上引导远程对象注册表的引用,或用于创建一个接受对特定端口调用的远程对象注册表。

注意,getRegistry 调用并不实际生成到远程主机的连接。它只创建对远程注册表的本地引用,即便远程主机上没有正运行的注册表,它也会成功创建一个引用。因此,调用作为此方法的结果返回的远程注册表的后续方法可能会失败。

方法摘要

static Registry

createRegistry(int port)
创建并导出接受指定 port 请求的本地主机上的 Registry 实例。

static Registry

createRegistry(int port,RMIClientSocketFactory csf, RMIServerSocketFactory ssf) 在本地主机上创建并导出 Registry 实例,该本地主机使用的是与该实例通信的自定义套接字工厂。

static Registry

getRegistry() 返回本地主机在默认注册表端口 1099 上对远程对象 Registry 的引用。

static Registry

getRegistry(int port)
返回本地主机在指定 port 上对远程对象 Registry 的引用。

static Registry

getRegistry(String host) 返回指定 host 在默认注册表端口 1099 上对远程对象 Registry 的引用。

static Registry

getRegistry(String host, int port)
返回指定的 host 和 port 上对远程对象 Registry 的引用。

static Registry

getRegistry(String host, int port,RMIClientSocketFactory csf) 返回本地创建的指定 host 和 port 上对远程对象 Registry 的远程引用。

 

例:

importjava.rmi.RemoteException;

importjava.rmi.registry.LocateRegistry;

importjava.rmi.registry.Registry;

publicclass T {

    publicstaticvoid main(String[] args) {

        //注册管理器 

        Registry registry =null

        try

            // 创建一个服务注册管理器 

            registry = LocateRegistry.createRegistry(8088); 

        } catch (RemoteException e) { 

              e.printStackTrace();

       

        try

            // 创建一个服务 

            RemoteServiceIml remoteService =

new RemoteServiceIml(); 

            // 将服务绑定命名 

            registry.rebind("remoteService",remoteService); 

            System.out.println("bind remoteService"); 

        } catch (RemoteException e) { 

               e.printStackTrace();

       

   }

}

写客户端

客户端所用类和服务端一样,仅仅方法不一样。

例:

importjava.rmi.AccessException;

importjava.rmi.NotBoundException;

importjava.rmi.RemoteException;

importjava.rmi.registry.LocateRegistry;

importjava.rmi.registry.Registry;

publicclass C {

   publicstaticvoidmain(String[] args) {

      //注册管理器 

        Registry registry =null

        try

            // 获取服务注册管理器 

            registry = LocateRegistry.getRegistry("127.0.0.1",8088); 

            // 列出所有注册的服务 

            String[] list =registry.list(); 

            for(String s : list){ 

                System.out.println(s); 

           

        } catch (RemoteException e) { 

       

        try

            // 根据命名获取服务 

            IRemoteService remoteService =(IRemoteService) registry.lookup("remoteService"); 

            // 调用远程方法 

            String result =remoteService.excavate(null,null;

            // 输出调用结果 

            System.out.println("result from remote : " + result); 

        } catch (AccessException e) { 

               e.printStackTrace();

        } catch (RemoteException e) { 

           e.printStackTrace();

        } catch (NotBoundException e) { 

           e.printStackTrace(); 

       

   }

}

 

原创粉丝点击