`
fengshujuan
  • 浏览: 160333 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

一 .RMI概述
RMI(Remote Method Invocation)
      RMI是分布式对象软件包,它简化了在多台计算机上的JAVA应用之间的通信。必须在jdk1.1以上

RMI用到的类
       java.rmi.Remote                     所有可以被远程调用的对象都必须实现该接口
       java.rmi.server.UnicastRemoteObject    所有可以被远程调用的对象都必须扩展该类

什么是RMI
      远程方法调用是一种计算机之间对象互相调用对方函数,启动对方进程的一种机制,
使用这种机制,某一台计算机上的对象在调用另外一台计算机上的方法时,使用的程
序语法规则和在本地机上对象间的方法调用的语法规则一样。

优点
这种机制给分布计算的系统设计、编程都带来了极大的方便。
只要按照RMI规则设计程序,可以不必再过问在RMI之下的网络细节了,如:TCP和Socket等等。
任意两台计算机之间的通讯完全由RMI负责。调用远程计算机上的对象就像本地对象一样方便。

1、面向对象:
RMI可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型。
也就是说,可以将类似Java哈西表这样的复杂类型作为一个参数进行传递。

2、可移动属性:
RMI可将属性从客户机移动到服务器,或者从服务器移动到客户机。

3、设计方式:
对象传递功能使您可以在分布式计算中充分利用面向对象技术的强大功能,如二层和三层结构系统。
如果用户能够传递属性,那么就可以在自己的解决方案中使用面向对象的设计方式。
所有面向对象的设计方式无不依靠不同的属性来发挥功能,如果不能传递完整的对象——包括实现和类型
——就会失去设计方式上所提供的优点。

4、安全性:
RMI使用Java内置的安全机制保证下载执行程序时用户系统的安全。
RMI使用专门为保护系统免遭恶意小程序侵害而设计的安全管理程序。
5、便于编写和使用
RMI使得Java远程服务程序和访问这些服务程序的Java客户程序的编写工作变得轻松、简单。
远程接口实际上就是Java接口。
为了实现RMI的功能必须创建远程对象任何可以被远程调用的对象必须实现远程接口。但远程
接口本身并不包含任何方法。因而需要创建一个新的接口来扩展远程接口。
新接口将包含所有可以远程调用的方法。远程对象必须实现这个新接口,由于新的接口扩展了
远程接口,实现了新接口,就满足了远程对象对实现远程接口的要求,所实现的每个对象都将
作为远程对象引用。

个人总结:
      RMI说白了,就是提供了一种远程的方法调用。 这种调用简单方便,可以传递复杂java对象。现在流行的j2ee中的EJB的底层实现技术就是RMI,EJB的调用就是经过封装的,更高级的RMI调用。


下面我们就来写一个RMI的程序:

一.创建RMI程序的6个步骤:
1、定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。
2、定义一个实现该接口的类。
3、使用RMIC程序生成远程实现所需的残根和框架。
4、创建一个服务器,用于发布2中写好的类。
5. 创建一个客户程序进行RMI调用。
6、启动rmiRegistry并运行自己的远程服务器和客户程序。

二. 程序详细说明

1.定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface I_Hello extends java.rmi.Remote     //需要从Remote继承
{
         public String SayHello() throws RemoteException;     //需要抛出remote异常
}

     上面例子我们定义一个返回字符串的远程方法 SayHello(),这个远程接口 I_Hello必须是public的 ,它必须从java.rmi.Remote继承而来,接口中的每一个方法都必须抛出远程异常java.rmi.RemoteException。

抛出这个异常的原因
由于任何远程方法调用实际上要进行许多低级网络操作,因此网络错误可能在调用过程中随时发生。
因此,所有的RMI操作都应放到try-catch块中。
   
2、定义一个实现该接口的类。

import java.io.PrintStream;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

public class Hello extends UnicastRemoteObject     //必须从UnicastRemoteObject    继承
                     implements I_Hello
{
          public Hello() throws RemoteException       //需要一个抛出Remote异常的默认初始化方法
          {
          }

          public String SayHello()       //这个是实现I_Hello接口的方法
          {
             return "Hello world !!";
          }
}

实现接口的类必须继承UnicastRemoteObject类。
扩展java.rmi.server.UnicastRemoteObject
UnicastRemoteObject顾名思义,是让客户机与服务器对象实例建立一对一的连接。

3、使用RMIC程序生成远程实现所需的残根Stub 和 框架。
     2中的Hello 编译好以后,我们就可以用RMIC命令来生成残根Stub
     在Dos窗口里,到Hello.class 所在目录,运行以下命令:
     rmic Hello
    
     命令执行完以后,将会在当前目录生成一个 Hello_Stub.class 这个就是我们远程调用时需要的类

参考:
在RMI中,客户机上生成的调动调用参数和反调动返回值的代码称为残根。有的书上称这部分代码为“主干”。
服务器上生成的反调动调用参数和进行实际方法调用调动返回值的代码称为框架。
生成残根和框架的工具
Rmic命令行工具(RMI Compiler)
格式:
Rmic classname

4、创建一个服务器,用于发布2中写好的类。

      import java.rmi.*;
public class RMI_Server
{
      public static void main(String[] args)
      {
          try
          {
              Hello hello = new Hello();                  //实例化要发布的类
              Naming.rebind("RMI_Hello", hello);        //绑定RMI名称 进行发布
              System.out.println("=== Hello server Ready === ");
          }
          catch(Exception exception)
          {
              exception.printStackTrace();
          }
      }
}

5. 创建一个客户程序进行RMI调用。

import java.rmi.*;
public class RMI_Client {
      public static void main(String[] args) {
          try
          {
             I_Hello hello = (I_Hello) Naming.lookup("RMI_Hello");    //通过RMI名称查找远程对象
              System.out.println(hello.SayHello());                          //调用远程对象的方法
          } catch (Exception e)
          {
            e.printStackTrace();
          }
      }

}

Naming.lookup("RMI_Hello") 其中的参数“RMI_Hello”只是针对本机的RMI查找,如果是异地的RMI调用请参照    rmi://127.0.0.1:1099/RMI_Hello         端口1099是默认的RMI端口,如果你启动 rmiregistry 的时候(见第6点)没有指定特殊的端口号,默认就是1099

到此 我们 所有的代码编写都完成了,不过不要急着去运行,请跟随第6点去运行,因为rmi 调用还会遇到一些特别的情况,偶花了牛劲,才找到原因的,许多刚用RMI的人,常常被这些问题搞得吐血

6、启动rmiRegistry并运行自己的远程服务器和客户程序。
1)服务器的运行
      先在DOS下运行 rmiregistry       这个命令是开启RMI的注册服务,开启以后我们的server程序才能调用rebing方法发布我们的类

      然后,运行我们的server程序    RMI_Server      这里是最容易出错的,参见下面注意事项。
       注意:
           如果提示找不到Stub类,这个需要用下面的命令来运行
java.exe -Djava.rmi.server.codebase=file:/E:\MIS_Interface\momo\TestEasy\classes/    RMI_Server

蓝字部分指定了stub类的路径。

    有人会问,我已经把stub 通过-classpath 加到类路径里面了,为什么还没有提示这个错误呢?原因是这样的: 这里提示的找不到stub类,不是由你写的RMI_Server这个程序引起的,是由rmi注册服务器报告的异常,也就是我们前面启动的 rmiregistry ,因为你写的RMI_Server 要求RMI注册服务器注册一个新的类,自然RMI服务器必须知道你的类放在哪里,所以我们通过    -Djava.rmi.server.codebase 这个运行参数来指定
    你也可以通过修改操作系统的classpath 环境变量 来指定stub的位置,只不过太麻烦

2) 客户端的运行
        直接运行RMI_Client    即可    注意 把 Stub 和 接口 I_Hello 加到类路径里
   
      通常第一次运行 客户端都会报一个错误:     Access    XXXX 不记得具体的了,反正就是“访问权限限制”, 这是因为RMI的服务需要授权,外部程序才能访问,所以我们要改动 jre的安全配置文件,来开放权限,    具体如下:

     打开你的jdk目录下的这个文件 C:\Program Files\Java\jdk1.5.0_04\jre\lib\security\java.policy
在文件最后加入下面代码:
grant {
             permission java.net.SocketPermission "*:1024-65535",
                  "connect,accept";
             permission java.net.SocketPermission "*:80","connect";
          };
此代码,开放了端口的connect访问权限

注意 你应该修改服务器那台机子的安全配置文件,也就是你运行 rmiregistry 和 RMI_Server的机子
另外,很多人修改完以后,仍然报这个错误,多数情况是由于你没有修改到正确的jdk 下的文件,而是修改到其他jdk的文件, 我们安装oracle , Weblogic等等软件的时候都会自带一个 jdk,他们会自动在操作系统的环境变量里面 加入jdk的路径,所以,你先要确定你运行服务器端程序是用哪个jdk,再修改这个jdk下的配置文件,确定当前jdk的路径很简单    开始 -》运行-》rmiregistry 看看这个DOS窗口标题 的路径,就是你当前系统默认jdk的路径了

客户端正常运行以后,就会出现以下结果:
Hello world !!

这些字符是通过RMI调用远程服务器的类返回的结果

分享到:
评论

相关推荐

    RMI 零基础入门与实例

    没有使用过RMI的学者可以参考本资源的实例,比较适用于没有RMI基础的学者,使用分布式编程

    rmi实例详解

    RMI的实例详解,可以学习到RMI的一些简单的操作,是很入门的哪种文档

    spring RMI 实例

    spring 对 RMI 的封装 一个很精简的例子,用于springRMI的入门学习很好 调试通过咯

    JAVA RMI入门教程

    没有使用过RMI的学者来说这是一个很好的资源,很清晰很明确的讲述了RMI的工作原理和基本实例,很好的入门教材

    RMI入门(二)实例 --- 亲自将代码调试成功

    NULL 博文链接:https://wulinhaoxia5.iteye.com/blog/1526803

    java rmi demo

    java rmi入门级实例:分为三个javase项目,rmi-api(存放公共的接口和实体),rmi-server(rmi服务器端),rmi-client(rmi客户端),其中服务端和客户端都依赖rmi-api项目

    javaRMIDemo实例

    java 的rmi 远程过程调用入门实例 希望可以帮到需要的人哈哈哈

    Hessian学习入门实例

    这是一个Hessian入门学习的实例,程序包是一个web工程,使用intellij idea + Maven开发,其中通过两个方式展示了使用Hessian实现RMI的原理,一个是访问jsp页面,一个是在代码中手工创建client。对于Hessian Servlet...

    JSP快速入门教程

    6 实例:hello.jsp  创建一JSP快速入门教程 第一讲(参考《Java Web程序设计基础教程》第1章) 1 JSP 和 Java的关系  一般Java指的标注版 Java SE  另外两个版本:Java EE 和 Java ME  JSP属于Java EE的一部分。...

    java高手真经 光盘源码

    javarmi.zip 24.RMI编程(HelloWorld例、计算器实例) javacorba.zip 25.Corba编程(HelloWorld例、计算器实例) 第6部分(4个程序包) javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java...

    Java高手真经(编程基础卷)光盘全部源码 免积分

    javarmi.zip 24.RMI编程(HelloWorld例、计算器实例) javacorba.zip 25.Corba编程(HelloWorld例、计算器实例) 第6部分(4个程序包) javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java...

    Java高手真经(编程基础卷)光盘全部源码

    javarmi.zip 24.RMI编程(HelloWorld例、计算器实例) javacorba.zip 25.Corba编程(HelloWorld例、计算器实例) 第6部分(4个程序包) javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java泛型...

    java网络编程-孙卫琴 书籍源代码 (17个章节项目)

    java网络编程-孙卫琴 书籍源代码 (17个章节项目) 很好的基本入门网络编程实例 包含 io nio关联接口 rmi接口类 详解和实战

    深入掌握J2EE编程技术(卷二)

    本书全面介绍了JSP层,EJB层和EIS层的设计思想与编程技术,涉及的内容包括:JDBC,JNDI,LDAP,Servlet,JSP,Taglib,EJB,J2EE Connector,SAX与DOM,RMI,CORBA,JavaMail和JMS。这些内容基本覆盖了J2EE平台开发...

    深入掌握J2EE编程技术(卷一)

    本书全面介绍了JSP层,EJB层和EIS层的设计思想与编程技术,涉及的内容包括:JDBC,JNDI,LDAP,Servlet,JSP,Taglib,EJB,J2EE Connector,SAX与DOM,RMI,CORBA,JavaMail和JMS。这些内容基本覆盖了J2EE平台开发...

    清华大学JAVA教程

    这套教程应该是非常酷的JAVA入门与提高的资料,它的目标就是: 通过本门课程的学习可以使学生掌握Java语言的基本语法和编程规范;尤其是掌握用Java语言进行网络编程的技巧;同时Java语言是一门面向对象的语言,通过...

    Quartz-Job-Scheduling-Framework-中文版-V0.9.1.zip

    以及如何通过 java.util.Properties 实例或默认 quartz.properties 文件创建 Scheduler。 第四章. 部署 Job (第二部分) 内容提要:如何管理 Scheduler(启动、停止、Standby 模式)。还介绍了 Job、...

    Java项目开发与毕业设计指导

    Ch11:基于RMI分布计算实例 安装JDK、配置环境变量,编译java源文件(可以用eclipse自动编译也可以手动命令行下编译),然后命令行下运行如下命令启动服务器端: java rmi.NetS 2000 (端口号为2000) 键入...

Global site tag (gtag.js) - Google Analytics