• Java中间件之RMI及实例介绍 · zijian's blog


    RMI介绍

      远程方法调用(Remote Method Invocation)是Sun公司规定的允许在不同的JAVA虚拟机之间进行对象间通信的一种规范。在RMI中,JVM可以位于一个或多个计算机上,其中一个JVM可以调用存储在另一个JVM中的对象方法。这就使得应用程序可以远程调用其他对象方法,从而达到分布式计算的目的,以共享各个系统的资源和处理能力。

      除了RMI外,基于JAVA的实现不同JAVA虚拟机上的应用程序之间通信技术主要有两种:套接字JAVA消息服务(JMS)

      使用套接字是实现程序间通信的最为灵活和强大的方式。但是它必须通过应用级协议进行通信,要求应用程序之间使用同样的协议,并且要求设计通信过程中的错误判断等。

      JMSRMI的区别在于,采用JMS服务,对象是物理上被异步地从网络的某个JVM上直接移动到另一个JVM上。而RMI对象是绑定在本地JVM上,只有函数参数和返回值是通过网络传送的

    RMI开发应用程序的一般步骤

    1. 定义远程接口
    2. 实现这个远程接口
    3. 生成stub(客户代理)和skeleton(服务器实体)
    4. 编写使用远程对象的客户程序
    5. 启动注册表并登记远程对象
    6. 运行服务器和客户程序

    Eclipse中RMI环境搭建

    1. 首先下载Eclipse的RMI开发插件 下载地址:http://www.genady.net/rmi/v20/downloads.html
    2. 解压缩将net.genady.rmi_2.5.0文件夹下的两个文件拷贝到eclipse安装目录下,覆盖同名的两个文件夹
    3. 重启eclipse即可在快捷栏看到RMI插件标志

    RMI图标

    简单实例

    1. 定义远程接口

      1
      2
      3
      4
      5
      6
      7
      8
      package RMIinterface;

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

      public interface extends Remote{
      public String sayHello ()throws RemoteException;
      }

      创建一个远程接口时,必须遵守下列规则:

      1. 远程接口必须为public
      2. 远程接口必须继承java.rmi.Remote 除应用程序本身有关异常外,
      3. 远程接口中的每个方法都必须在自己的 throws中声明java.rmi.RemoteException
      4. 作为参数或返回值传递的一个远程对象,必须声明为远程接口,不可 声明为实现类。
    2. 实现这个接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      package rmiIMP;

      import java.rmi.RemoteException;
      import java.rmi.server.UnicastRemoteObject;

      import RMIinterface.iHello;

      public class rmiIMP extends UnicastRemoteObject implements {

      private static final long serialVersionUID = 1L;

      public rmiIMP() throws RemoteException {
      }


      public String sayHello() throws RemoteException {
      return "hello zhang";
      }



      }
    3. 构建服务器程序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      package rmiServer;

      import java.net.MalformedURLException;
      import java.rmi.AlreadyBoundException;
      import java.rmi.Naming;
      import java.rmi.RemoteException;
      import java.rmi.registry.LocateRegistry;

      import rmiIMP.rmiIMP;
      import RMIinterface.iHello;

      public class helloServer {

      public static void main(String[] args) {

      try {
      iHello ihello = new rmiIMP();
      LocateRegistry.createRegistry(1099);
      Naming.bind("rmi://localhost:1099/iHello",ihello);


      } catch (RemoteException e) {
      System.out.println("创建远程对象异常!");
      e.printStackTrace();
      } catch (MalformedURLException e) {
      System.out.println("URL异常!");
      e.printStackTrace();
      } catch (AlreadyBoundException e) {
      System.out.println("绑定异常!");
      e.printStackTrace();
      }

      }

      }
    4. 构建客户程序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      package rmiClient;

      import java.net.MalformedURLException;
      import java.rmi.Naming;
      import java.rmi.NotBoundException;
      import java.rmi.RemoteException;

      import RMIinterface.iHello;

      public class helloClient {

      public static void main(String[] args) {
      try {
      iHello ihello = (iHello) Naming.lookup("rmi://localhost:1099/iHello");
      System.out.println(ihello.sayHello());


      } catch (MalformedURLException e) {
      e.printStackTrace();
      } catch (RemoteException e) {
      e.printStackTrace();
      } catch (NotBoundException e) {
      e.printStackTrace();
      }
      }

      }
    5. 打开cmd窗口,对所在位置的接口进行编译。

    6. 右键该项目,打开运行配置窗口,找到RMI VM Properties后,对java.security.policyjava.rmi.server.codebase进行配置
      RMI配置

    7. 然后在RMI Application方式下运行服务器程序,在Java Application方式下运行客户程序。

    结合XML编程的RMI实例——航班信息查询(通过查询目的地显示到达该目的地的所有航班信息)

    1. 编写多个XML文件,每个XML文件表示一所航空公司。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      <?xml version="1.0" encoding="GB2312"?>
      <!DOCTYPE 航班列表 [
      <!ELEMENT 航班列表 (航班)*>
      <!ELEMENT 航班 (编号,始发地,目的地,出发时间,到达时间)>
      <!ELEMENT 编号 (#PCDATA)>
      <!ELEMENT 始发地 (#PCDATA)>
      <!ELEMENT 目的地 (#PCDATA)>
      <!ELEMENT 出发时间 (#PCDATA)>
      <!ELEMENT 达到时间 (#PCDATA)>
      ]>
      <航班列表>
      <航班>
      <编号>101</编号>
      <始发地>武汉</始发地>
      <目的地>北京</目的地>
      <出发时间>2016-05-02 16:30</出发时间>
      <到达时间>2016-05-02 19:25</到达时间>
      </航班>
      <航班>
      <编号>102</编号>
      <始发地>深圳</始发地>
      <目的地>成都</目的地>
      <出发时间>2016-05-03 10:15</出发时间>
      <到达时间>2015-05-03 14:00</到达时间>
      </航班>
      <航班>
      <编号>103</编号>
      <始发地>北京</始发地>
      <目的地>天津</目的地>
      <出发时间>2016-05-02 16:30</出发时间>
      <到达时间>2016-05-02 19:25</到达时间>
      </大专栏  Java中间件之RMI及实例介绍 · zijian's blog"name">航班>
      </航班列表>
    2. 定义远程接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      package searchF;

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

      public interface SearchFlight extends Remote{
      public void SearchF()throws RemoteException;

      }
    3. 实现这个远程接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      package searchIMP;

      import java.io.File;
      import java.rmi.RemoteException;
      import java.rmi.server.UnicastRemoteObject;
      import java.util.Scanner;

      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;

      import org.w3c.dom.Document;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;

      import searchF.SearchFlight;

      public class searchFIMP extends UnicastRemoteObject implements SearchFlight{


      private static final long serialVersionUID = 1L;

      public searchFIMP() throws RemoteException {
      super();
      }


      public void SearchF() throws RemoteException {
      try {

      //获得一个XML文件的解析器
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      //解析XML文件生成DOM文档的接口类,以便访问DOM
      DocumentBuilder builder = factory.newDocumentBuilder();
      System.out.print("请输入您要查询的目的地:");
      Scanner scan = new Scanner(System.in);
      String city = scan.nextLine();
      scan.close();
      int[] temp = new int[3];
      int[] count = new int[3];
      for(int k = 0 ; k < 3; k++){
      String airport = "flight"+ (k+1) +".xml";
      //Document接口描述了对应于整个XML文件的文档树
      Document document = builder.parse(new File(airport));
      //获取“航班”元素的子节点列表
      NodeList nodelist = document.getElementsByTagName("航班");
      temp[k] = nodelist.getLength();
      count[k] = 0;
      for (int i = 0; i < nodelist.getLength(); i++) {
      NodeList nl = nodelist.item(i).getChildNodes();
      if(getFlight(nl, city)) {
      if(k == 0 && count[k] == 0)
      System.out.println("到达该目的地的所有航班信息如下:");
      count[k] ++;
      for (int j = 0; j < nl.getLength(); j++) {
      Node cnode = nl.item(j);
      if (cnode.getNodeType() == Node.ELEMENT_NODE) {
      System.out.println(" -->" + cnode.getNodeName() + ": " + cnode.getTextContent());
      }
      }
      System.out.println();
      }else
      temp[k]--;
      }
      }
      if(temp[0] + temp[1] + temp[2] == 0 )
      System.out.println("没有到达该目的地的航班信息!");
      else{
      int sum = count[0]+count[1]+count[2];
      System.out.println("共有"+ sum + "条航班信息!");
      }
      }
      catch (Exception e) {
      e.printStackTrace();
      }
      }

      //判断所当前航班的目的地城市是否为所查询城市,若是,则返回true
      public static boolean getFlight(NodeList nodelist, String str) {
      boolean temp = false;
      for (int i = 0; i < nodelist.getLength(); i++) {
      Node node = nodelist.item(i);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
      if (node.getTextContent().equals(str) && node.getNodeName().equals("目的地")) {
      temp = true;
      }
      }
      }
      return temp;
      }
      }
    4. 构建服务器程序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      package searchServer;

      import java.net.MalformedURLException;
      import java.rmi.AlreadyBoundException;
      import java.rmi.Naming;
      import java.rmi.RemoteException;
      import java.rmi.registry.LocateRegistry;
      import searchF.SearchFlight;
      import searchIMP.searchFIMP;

      public class searchFServer {

      public static void main(String[] args) {
      try {
      searchFIMP imp = new searchFIMP();
      LocateRegistry.createRegistry(1099);
      Naming.bind("rmi://localhost:1099/searchFIMP",imp);

      } catch (RemoteException e) {
      System.out.println("创建远程对象异常!");
      e.printStackTrace();
      } catch (MalformedURLException e) {
      System.out.println("URL异常!");
      e.printStackTrace();
      } catch (Exception e){
      e.printStackTrace();
      }
      }
      }
    5. 构建客户程序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      package searchClient;

      import java.net.MalformedURLException;
      import java.rmi.Naming;
      import java.rmi.NotBoundException;
      import java.rmi.RemoteException;
      import searchF.SearchFlight;

      public class searchFClient {

      public static void main(String[] args) {
      try {
      SearchFlight searchF = (SearchFlight) Naming.lookup("rmi://localhost:1099/searchFIMP");
      searchF.SearchF();


      } catch (MalformedURLException e) {
      e.printStackTrace();
      } catch (RemoteException e) {
      e.printStackTrace();
      } catch (NotBoundException e) {
      e.printStackTrace();
      }
      }

      }
    6. 以RMI Application方式运行服务器程序,正常运行客户端程序,运行结果如下:
      RMI运行结果

  • 相关阅读:
    Python 五个知识点搞定作用域
    python中的三元表达式(三目运算符)
    Python中 sys.argv的用法简明解释
    pycharm多行批量缩进和反向缩进快捷键
    Python终端如何输出彩色字体
    第8周LeetCode记录
    第7周Leetcode记录
    《Java核心技术》第九章读书笔记(集合)
    《Java核心技术》第八章读书笔记(泛型)
    《Java核心技术》第七章读书笔记(异常处理)
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12239639.html
Copyright © 2020-2023  润新知