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插件标志

简单实例

  1. 定义远程接口

    12345678
    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. 实现这个接口
    12345678910111213141516171819202122
    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. 构建服务器程序
    1234567891011121314151617181920212223242526272829303132333435
    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. 构建客户程序
    123456789101112131415161718192021222324252627
    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进行配置
  7. 然后在RMI Application方式下运行服务器程序,在Java Application方式下运行客户程序。

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

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

    123456789101112131415161718192021222324252627282930313233
    <?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. 定义远程接口
    123456789
    package searchF;
    
    import java.rmi.Remote;import java.rmi.RemoteException;
    
    public interface SearchFlight extends Remote{    public void SearchF()throws RemoteException;
    
    }
  3. 实现这个远程接口
    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
    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. 构建服务器程序
    1234567891011121314151617181920212223242526272829
    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. 构建客户程序
    1234567891011121314151617181920212223242526
    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方式运行服务器程序,正常运行客户端程序,运行结果如下:

原文地址:https://www.cnblogs.com/lijianming180/p/12239639.html

时间: 2024-08-01 06:23:47

Java中间件之RMI及实例介绍 · zijian‘s blog的相关文章

Java 程序连接 Informix 数据库方法实例介绍

Java 程序连接 Informix 数据库方法实例介绍 Informix 是一种应用广泛的关系型数据库服务器,支持多种类型的客户端连接程序,包括 .Net.Java.PHP 等.对于 Java 程序,Informix 支持两种 JDBC 供客户端连接.本文对这两种 JDBC 进行详细介绍,并给出 Java 使用两种方法连接 Informix 的方法和实例,对数据库开发人员具有指导意义 开您的试用 概述 Informix 是一种应用广泛的关系型数据库服务器,支持多种类型的客户端连接程序,包括 .

java远程调用rmi入门实例

RMI是Java的一组拥护开发分布式应用程序的API.RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol).简单地说,这样使原先的程序在同一操作系统的方法调用.变成了不同操作系统之间程序的方法调用.因为J2EE是分布式程序平台.它以RMI机制实现程序组件在不同操作系统之间的通信. 比方,一个EJB能够通过RMI调用Web上还有一台机器上的EJB远程方法. 用例server端结构大概如此 首先定义要传送的实

Java 集合之HashSet常用方法实例介绍

一.简介HashSet是Set常见的子类对象,此类实现Set接口,由哈希表(实际为HashMap实例)支持. 对集合的迭代次序不作任何保证; 特别是,它不能保证订单在一段时间内保持不变.这个类允许null元素.这个类提供了基本操作(add,remove,contains和size)固定的时间性能,假定哈希函数将分散的桶中正确的元素. 迭代此集合需要与HashSet实例的大小(元素数量)和后台HashMap实例(桶数)的"容量"的总和成比例的时间. 因此,如果迭代性能很重要,不要将初始容

大型网站系统与Java中间件实践

大型网站系统与Java中间件实践(贯通分布式高并发高数据高访问量网站架构与实现之权威著作,九大一线互联网公司CTO联合推荐) 曾宪杰 著   ISBN 978-7-121-22761-5 2014年4月出版 定价:65.00元 340页 16开 编辑推荐 到底是本什么书,拥有这样一份作序推荐人列表:阿里集团章文嵩博士|新浪TimYang|去哪网吴永强|丁香园冯大辉|蘑菇街岳旭强|途牛汤峥嵘|豆瓣洪强宁|淘宝陈皓/林昊-- 这本书出自淘宝技术部总监之手,他也是淘宝近10年来历次技术飞跃的参与者.贡

Java 代码优化过程的实例介绍

衡量程序的标准 衡量一个程序是否优质,可以从多个角度进行分析.其中,最常见的衡量标准是程序的时间复杂度.空间复杂度,以及代码的可读性.可扩展性.针对程序的时间复杂度和空间复杂度,想要优化程序代码,需要对数据结构与算法有深入的理解,并且熟悉计算机系统的基本概念和原理:而针对代码的可读性和可扩展性,想要优化程序代码,需要深入理解软件架构设计,熟知并会应用合适的设计模式. 首先,如今计算机系统的存储空间已经足够大了,达到了 TB 级别,因此相比于空间复杂度,时间复杂度是程序员首要考虑的因素.为了追求高

实例介绍 Java(android) 回调函数使用方法

在Android开发中经常用到回调机制,其中最典型的就是控件被触发的实现方式,简单而言,如Button被Click后,是系统调用了OnClick方法,而我们为Button注册了OnClickListener监听器,当被触发Click后,OnClickListener中的OnClick方法就会被回调,我们就能在其中执行相应操作了. 下面举一个简单的例子介绍回调的实现方式: 回调函数使用的简单例子 程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序.程序员B要让a调用自己的程序

关于metaspolit中进行JAVA反序列化渗透RMI的原理分析

一.背景: 这里需要对java反序列化有点了解,在这里得推广下自己的博客嘛,虽然写的不好,广告还是要做的.原谅我: 1.java反序列化漏洞原理研习 2.java反序列化漏洞的检测 二.攻击手法简介 针对这个使用msf攻击需要大家看一篇文章:JMX RMI Exploit 实例 , 鸣谢,确实学到了很多,膜拜大牛 , 简要介绍下攻击手法: (1)下载mjet模块:下载连接mjet,如果是mac电脑安装好metaspolit以后可以直接使用git clone命令下载到metaspolit的父目录下

Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 概要  和学习ArrayList一样,接下来呢,我们先对LinkedList有个整体认识,然后再学习它的源码:最后再通过实例来学会使用LinkedList.内容包括:第1部分 LinkedList介绍第2部分 LinkedList数

Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解ArrayList.先对ArrayLis