`
lzj0470
  • 浏览: 1273581 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

RMI实例分析

    博客分类:
  • java
阅读更多

分布式对象技术主要是在分布式异构环境下建立应用系统框架和对象构件。在应用系统框架的支撑下,开发者可以将软件功能封装为更易管理和使用的对象,这些对象可以跨越不同的软、硬件平台进行互操作。目前,分布式互操作标准主要有Microsoft的COM/DCOM标准、Sun公司的Java RMI标准和OMG组织的CORBA标准。
原文地址:
http://blog.csdn.net/javamxj/archive/2005/02/06/282659.aspx


Java RMI简介

   远程方法调用(RMI,Remote Method Invocation)是jdk1.1中引入的分布式对象软件包,它的出现大大简化了分布异构环境中Java应用之间的通信。

   要使用RMI,必须构建四个主要的类:远程对象的本地接口、远程对象实现、RMI客户机和RMI服务器。RMI服务器生成远程对象实现的一个实例,并用一个专有的URL注册。RMI客户机在远程RMI服务器上查找服务对象,并将它转换成本地接口类型,然后像对待一个本地对象一样使用它。

   下面是一个简单的RMI实例,RMI客户机通过RMI服务器提供的方法输出一个语句。例子虽然很简单,但掌握了Java RMI调用的基本原理和方法,在实现复杂应用时,我们需要做的也只是完善远程对象的实现类而已。


RMI实例分析
 
1.远程对象的本地接口声明(RMIOperate.java)

  · 该类仅仅是一个接口声明,RMI客户机可以直接使用它,RMI服务器必须通过一个远程对象来实现它,并用某个专有的URL注册它的一个实例。
  · 远程接口扩展 java.rmi.Remote 接口。
  · 除了所有应用程序特定的例外之外,每个方法还必须在 throws 子句中声明 java.rmi.RemoteException(或 RemoteException 的父类)。

Hello.Java

  1. /* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */  
  2. import java.rmi.*;   
  3. // RMI本地接口必须从Remote接口派生   
  4. public interface Hello extends Remote {       
  5.   // 接口中的具体方法声明,注意必须声明抛出RemoteException       
  6.   String sayHello(String name) throws RemoteException;   
  7. }   
  8.     

<textarea class="java" style="display: none;" cols="100" rows="15" name="code">/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import java.rmi.*; // RMI本地接口必须从Remote接口派生 public interface Hello extends Remote {      // 接口中的具体方法声明,注意必须声明抛出RemoteException      String sayHello(String name) throws RemoteException; } </textarea>
2.远程对象实现类

  这个类应实现RMI客户机调用的远程服务对象的本地接口,它必须从UnicastRemoteObject继承,构造函数应抛出RemoteException异常。
HelloImpl.java

  1. /* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */  
  2. import java.rmi.*;   
  3. import javax.rmi.PortableRemoteObject;   
  4. public class HelloImpl extends PortableRemoteObject implements Hello {       
  5.   /* 构造函数 */       
  6.   public HelloImpl() throws RemoteException {    
  7.     super();       
  8.   }       
  9.   /* 实现本地接口中声明的'sayHello()'方法 */       
  10.   public String sayHello(String message) throws RemoteException {   
  11.     System.out.println("我在RMI的服务器端,客户端正在调用'sayHello'方法。 ");           
  12.     System.out.println("Hello  " + message);        return message;       
  13.   }   
  14. }   
  15.   

<textarea class="java" style="display: none;" cols="100" rows="15" name="code">/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import java.rmi.*; import javax.rmi.PortableRemoteObject; public class HelloImpl extends PortableRemoteObject implements Hello {      /* 构造函数 */      public HelloImpl() throws RemoteException {    super();      }      /* 实现本地接口中声明的'sayHello()'方法 */      public String sayHello(String message) throws RemoteException {    System.out.println("我在RMI的服务器端,客户端正在调用'sayHello'方法。 ");            System.out.println("Hello  " + message);        return message;      } } </textarea>
3.RMI服务器类

  该类创建远程对象实现类HelloImpl的一个实例,然后通过一个专有的URL来注册它。所谓注册就是通过Java.rmi.Naming.bind()方法或Java.rmi.Naming.rebind()方法,将HelloImpl实例绑定到指定的URL上。

  1. /* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */  
  2. import java.rmi.*;   
  3. public class HelloServer {       
  4.   public static void main(String[] args) {           
  5.     // 在服务器端设置安全机制                    
  6.     /*             
  7.     if (System.getSecurityManager() == null) {                 
  8.       System.setSecurityManager(new RMISecurityManager());              
  9.     }          
  10.     */  
  11.     try {               
  12.       System.out.println("开始 RMI Server ...");               
  13.       /* 创建远程对象的实现实例 */               
  14.       HelloImpl hImpl = new HelloImpl();               
  15.       System.out.println("将实例注册到专有的URL ");               
  16.       Naming.rebind("HelloService", hImpl);                           
  17.       System.out.println("等待RMI客户端调用...");               
  18.       System.out.println("");           
  19.     } catch (Exception e) {               
  20.       System.out.println("错误: " + e);           
  21.     }       
  22.   }   
  23. }   

<textarea class="java" style="display: none;" cols="100" rows="15" name="code">/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import java.rmi.*; public class HelloServer {      public static void main(String[] args) {            // 在服务器端设置安全机制                    /*              if (System.getSecurityManager() == null) {                    System.setSecurityManager(new RMISecurityManager());                }            */    try {                  System.out.println("开始 RMI Server ...");                  /* 创建远程对象的实现实例 */                  HelloImpl hImpl = new HelloImpl();                  System.out.println("将实例注册到专有的URL ");                  Naming.rebind("HelloService", hImpl);                              System.out.println("等待RMI客户端调用...");                  System.out.println("");            } catch (Exception e) {                  System.out.println("错误: " + e);            }      } } </textarea>
请注意有关 rebind 方法调用的下列参数:

第一个参数是 URL 格式的 java.lang.String,表示远程对象的位置和名字。
需要将 myhost 的值更改为服务器名或 IP 地址。否则,如果在 URL 中省略,则主机缺省值为当前主机,而且在 URL 中无需指定协议(例如“HelloServer”)。
在 URL 中,可以选择提供端口号:例如“//myhost:1234/HelloServer”。端口缺省值为 1099。除非服务器在缺省 1099 端口上创建注册服务程序,否则需要指定端口号。
第二个参数为从中调用远程方法的对象实现引用。
RMI 运行时将用对远程对象 stub 程序的引用代替由 hImpl 参数指定的实际远程对象引用。远程实现对象(如 HelloImpl 实例)将始终不离开创建它们的虚拟机。因此,当客户机在服务器的远程对象注册服务程序中执行查找时,将返回包含该实现的 stub 程序的对象。

4.RMI客户机类

  · RMI客户使用java.rmi.Naming.lookup()方法,在指定的远程主机上查找RMI服务对象,若找到就把它转换成本地接口RMIOperate类型。它与CORBA不同之处在于RMI客户机必须知道提供RMI服务主机的URL,这个URL可以通过rmi://host/path或rmi://host:port/path来指定,如果省略端口号,就默认使用1099。  
  · Java.rmi.Naming.lookup()方法可能产生三个异常:Java.rmi.RemoteException、Java.rmi.NotBoundException、java.net. MalformedURLException,三个异常都需要捕获。

  1. /* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */  
  2. import java.rmi.*;   
  3. public class HelloClient {       
  4.   public static void main(String[] args) {           
  5.     //   在服务器端设置安全机制                    
  6.     /*             
  7.     if (System.getSecurityManager() == null) {                 
  8.       System.setSecurityManager(new RMISecurityManager());              
  9.     }          
  10.     */                
  11.     /* 默认为本地主机和默认端口 */           
  12.     String host = "localhost:1099";           
  13.     /* 带输入参数时,将host设置为指定主机 */           
  14.     if (args.length > 0)               
  15.       host = args[0];          
  16.     try {               
  17.       /* 根据指定的URL定位远程实现对象 */               
  18.       /* “h”是一个标识符,我们将用它指向实现“Hello”接口的远程对象 */               
  19.       Hello h = (Hello) Naming.lookup("rmi://" + host + "/HelloService");                           
  20.       System.out.println("实现“Hello”接口的远程对象: " + h);               
  21.       System.out.println("我在客户端,开始调用RMI服务器端的'sayHello'方法");               
  22.       System.out.println("欢迎,  " + h.sayHello("javamxj blog"));           
  23.     } catch (Exception ex)    
  24.     {               
  25.       System.out.println("错误 " + ex);           
  26.     }       
  27.   }   
  28. }   

<textarea class="java" style="display: none;" cols="100" rows="15" name="code">/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import java.rmi.*; public class HelloClient {      public static void main(String[] args) {            //   在服务器端设置安全机制                    /*              if (System.getSecurityManager() == null) {                    System.setSecurityManager(new RMISecurityManager());                }            */                /* 默认为本地主机和默认端口 */            String host = "localhost:1099";            /* 带输入参数时,将host设置为指定主机 */            if (args.length > 0)                  host = args[0];          try {                  /* 根据指定的URL定位远程实现对象 */                  /* “h”是一个标识符,我们将用它指向实现“Hello”接口的远程对象 */                  Hello h = (Hello) Naming.lookup("rmi://" + host + "/HelloService");                              System.out.println("实现“Hello”接口的远程对象: " + h);                  System.out.println("我在客户端,开始调用RMI服务器端的'sayHello'方法");                  System.out.println("欢迎,  " + h.sayHello("javamxj blog"));            } catch (Exception ex)    {                  System.out.println("错误 " + ex);            }      } } </textarea>

5. 编译代码与运行系统:

  在MS-DOS环境下,创建一个D:\RMISample目录,把上面4个文件复制到这个目录下,然后在此目录下新建两个文件夹:client和server(把它们分别看作是客户端与服务端)。

(1).编译所有的源代码
   D:\RMISample> javac *.java

(2).生成客户端存根和服务器框架
   D:\RMISample> rmic HelloImpl
   这将生成HelloImpl_Stub.class和HelloImpl_Skel.class。
  ( 注:如果需要查看这两个类的源代码,可以使用“ rmic -keep HelloImpl”语句)

(3).把Hello.class、HelloClient.class、HelloImpl_Stub.class复制到client目录;
   把Hello.class、HelloServer.class、HelloImpl_Skel.class、HelloImpl_Stub.class 复制到server目录。

(4).启动RMI注册
   D:\RMISample\server>rmiregistry
  (注: 我是在命令控制台下运行这个系统的,必须开启三个控制台窗口,一个运行RMIRegistry,一个运行服务器,还有一个运行客户端。)

(5).运行和调用

● 在服务器上执行HelloServer
 D:\RMISample\server>java HelloServer

● 在本地客户机上运行HelloClient
 D:\RMISample\client>java HelloClient

● 在远程客户机上运行HelloClient(须指明RMI服务器主机名或IP地址)
  java HelloClient  222.222.34.34



  还有一点要注意,在上面的例子中我注释了安全管理的代码,如果把注释去掉,那么需要建立一个安全策略文件,比如其文件名为 policy.txt,内容如下:
grant {
permission java.security.AllPermission "", "";
};
这是一条简单的安全策略,它允许任何人做任何事,对于你的更加关键性的应用,你必须指定更加详细安全策略。把这个文件复制到Client和Server目录,然后如下运行:
D:\RMISample\server>java -Djava.security.policy=policy.txt HelloServer
D:\RMISample\client>java -Djava.security.policy=policy.txt HelloClient

<!---->
分享到:
评论

相关推荐

    RMI 零基础入门与实例

    **RMI实例分析:** 提供的`JAVA_RMI_实例.doc`文档可能包含了一个简单的RMI应用实例,通常包括以下部分: 1. **创建远程接口:**定义一个名为`MyRemoteInterface`的接口,声明如`sayHello()`等远程方法。 2. **...

    一个相当经典的RMI实例源代码及详细说明

    RMI(Remote Method Invocation,远程方法调用)是Java中的一种技术,用于构建分布式系统,使得在一台机器上的对象能够调用另一台机器上对象的方法,就像它们在同一个进程中一样。RMI使得开发者可以创建跨网络的、...

    中间件实验(rmi实例)

    中间件实验(RMI 实例)是 Java RMI(Remote Method Invocation,远程方法调用)的实验报告,旨在通过实验了解 Java RMI 的机制和开发流程。本实验报告主要介绍了 RMI 的基本概念、实验步骤、实验结果和结论分析等...

    rmi_java项目实例

    3. **RMI项目实例"RMIServer"分析**: - `RMIServer`可能包含了服务器端的主程序,它注册远程对象到RMI注册表,使得客户端可以通过名字查找并调用。 - 项目可能包含一个或多个远程接口类,定义了可供客户端调用的...

    Java RMI 可运行实例

    3. **运行RMI实例** - **启动RMI注册表**:运行`rmiregistry`命令启动RMI注册表服务。 - **编译代码**:确保所有的Java源代码都已正确编译为字节码文件。 - **运行服务器**:使用`java`命令运行服务器端程序,这...

    Spring(RMI)实例

    通过分析和实践这个Spring RMI实例,开发者可以学习到如何在Spring环境中设置和使用RMI,这对于理解和掌握分布式系统的设计原则,尤其是Java环境下的分布式服务实现非常有帮助。同时,这也是一个很好的起点,可以...

    07-RMI 利用分析.pdf

    文章中提到的RMI利用分析涉及到了RMI攻击向量,也就是通过RMI接口发起的安全攻击。攻击者可能会利用RMI中的漏洞来实施远程代码执行攻击,如RMI Serialization Attack演示,这通常涉及到恶意对象的序列化与反序列化。...

    RMI最简单的一个实例

    #### 二、RMI实例详解 本节将详细介绍一个简单的RMI示例程序,包括服务端接口定义、服务端实现、客户端调用等步骤。 ##### 1. 定义服务端接口 首先定义服务端接口 `AddServer`,该接口继承自 `Remote` 接口,并...

    spring rmi 源码

    Spring RMI(Remote Method Invocation)...通过分析服务端和客户端的源码,我们可以深入理解如何在Spring框架下实现和使用RMI远程调用,这对于任何希望在分布式系统中利用Spring的开发者来说都是一份宝贵的参考资料。

    RMI

    1. **服务器端**:创建远程对象实例,将其绑定到RMI注册表,指定一个唯一的名称。远程对象的实现需要继承`java.rmi.server.UnicastRemoteObject`或使用`UnicastRemoteObject.exportObject()`方法来暴露对象。 2. **...

    一个RMI的分布式应用的实例

    ### RMI分布式应用实例解析 #### 一、RMI简介及分布式应用原理 RMI (Remote Method Invocation) 是 Java 提供的一种远程方法调用技术,它允许开发者在不同的 JVM 上像调用本地方法那样调用远程方法。RMI 的主要...

    精通RMI程序代码

    - **案例分析**:通过实际项目或示例,展示如何在Java应用中集成和使用RMI。 学习和掌握RMI,不仅可以提升你的Java编程能力,更是在分布式系统和企业级应用开发中打开新视野的关键。通过实践和理解上述知识点,你将...

    RMI可运行的示例代码

    通过调试和分析这个示例,你可以更好地理解RMI的工作流程和实现细节。 总的来说,RMI是Java开发分布式应用程序的重要工具,它的概念和技术对于理解EJB和其他J2EE技术至关重要。通过实践这个RMI示例,你不仅能掌握...

    RMI例子

    3. **创建RMI服务器**:在服务端,你需要实例化远程对象,并将其注册到RMI注册表中。注册表的默认端口是1099。 ```java MyRemoteInterface remote = new MyRemoteImpl(); Naming.rebind("myRemoteService", remote)...

    RMI.rar_chat rmi_java rmi chat_rmi _rmi 聊天

    开发者可以通过阅读和分析这些代码来学习RMI的使用和聊天应用的构建。 此外,理解RMI的性能和限制也很重要。虽然RMI简化了分布式编程,但其性能受到网络延迟、序列化开销等因素影响。对于大型复杂系统,可能需要...

    zookeeper+rmi开发

    通过分析这些代码,你可以更深入地了解如何将ZooKeeper和RMI集成到你的分布式系统中,实现服务的注册、发现和跨网络的调用。 总之,"zookeeper+rmi开发"是一个利用ZooKeeper进行服务治理,通过RMI进行跨网络调用的...

    spring和RMI分布式整合源码

    这个“spring和RMI分布式整合源码”可能包含了一个实际项目中如何将这两种技术融合的实例。现在,我们将深入探讨Spring框架和RMI,以及它们在分布式环境中的整合应用。 首先,Spring是一个开源的Java应用程序框架,...

    利用RMI异步调用

    - **远程对象**:实现了远程接口的类,实例化后运行在服务器JVM上,可供客户端调用。 - **注册表**:RMI注册表是一个服务,用于将远程对象的引用与名称关联起来,使得客户端可以通过名称查找并调用远程对象。 2. ...

    JAVA RMI测试代码

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许Java对象在不同的网络环境中进行交互,就...通过分析这些代码,可以深入理解RMI的工作原理以及如何在实际项目中应用。

    RMI.rar_rmi

    Java远程方法调用(Remote Method Invocation,简称RMI)是Java平台中用于分布式计算的一种机制。它允许一个Java对象在某台...通过分析和运行这个例子,你可以更深入地了解RMI的各个组成部分以及它们如何协同工作。

Global site tag (gtag.js) - Google Analytics