版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、RMI是远程方法调用的简称,象其名称暗示的那样,它能够帮助我们查找并执行远程对象的方法。通俗地说,远程调用就象将一个class放在A机器上,然后在B机器中调用这个class的方法。我个人认为,尽管RMI不是唯一的企业级远程对象访问方案,但它却是最容易实现的。与能够使不同编程语言开发的CORBA不同的是,RMI是一种纯Java 解决方案。在RMI中,程序的所有部分都由Java编写。在看本篇文章时,我假定读者都已经具备了较扎实的Java基础知识,在这方面有欠缺的读者请自行阅读有关资料。概念我在前面已经提到,RMI是一种远程方法调用机制,其过程对于最终用户是透明的:在进行现场演示时,如果我不说它使用
2、了RNI,其他人不可能知道调用的方法存储在其他机器上。当然了,二台机器上必须都安装有Java虚拟机(JVM。其他机器需要调用的对象必须被导出到远程注册服务器,这样才能被其他机器调用。因此,如果机器A要调用机器B上的方法,则机器B必须将该对象导出到其远程注册服务器。注册服务器是服务器上运行的一种服务,它帮助客户端远程地查找和访问服务器上的对象。一个对象只有导出来后,然后才能实现RMI 包中的远程接口。例如,如果想使机器A中的Xyz对象能够被远程调用,它就必须实现远程接口。RMI需要使用占位程序和框架,占位程序在客户端,框架在服务器端。在调用远程方法时,我们无需直接面对存储有该方法的机器。在进行数
3、据通讯前,还必须做一些准备工作。占位程序就象客户端机器上的一个本机对象,它就象服务器上的对象的代理,向客户端提供能够被服务器调用的方法。然后,Stub就会向服务器端的Skeleton发送方法调用,Skeleton就会在服务器端执行接收到的方法。Stub和Skeleton之间通过远程调用层进行相互通讯,远程调用层遵循TCP/IP协议收发数据。下面我们来大致了解一种称为为“绑定”的技术。客户端无论何时要调用服务器端的对象,你可曾想过他是如何告诉服务器他想创建什么样的对象吗?这正是“绑定”的的用武之地。在服务器端,我们将一个字符串变量与一个对象联系在一起(可以通过方法来实现,客户端通过将那个字符串传
4、递给服务器来告诉服务器它要创建的对象,这样服务器就可以准确地知道客户端需要使用哪一个对象了。所有这些字符串和对象都存储在的远程注册服务器中。在编程中需要解决的问题在研究代码之前,我们来看看必须编写哪些代码:远程对象:这个接口只定义了一个方法。我们应当明白的是,这个接口并非总是不包括方法的代码而只包括方法的定义。远程对象包含要导出的每个方法的定义,它还实现Java.rmi中的远程接口。远程对象实现:这是一个实现远程对象的类。如果实现了远程对象,就能够覆盖该对象中的所有方法,因此,远程对象的实现类将真正包含我们希望导出的方法的代码。远程服务器:这是一个作为服务器使用的类,它是相对于要访问远程方法的
5、客户端而言的。它存储着绑定的字符串和对象。远程客户端:这是一个帮助我们访问远程方法提供帮助的类,它也是最终用户。我们将使用查找和调用远程方法的方法在该类中调用远程方法。编程我们将首先编写远程对象,并将代码保存为名字为AddServer.Java的文件: import Java.rmi.*;public interface AddServer extends Remote public int AddNumbers(int firstnumber,int secondnumber throws RemoteException;我们来看看上面的代码。首先,为了使用其内容,我们导入rmi包。然后,我
6、们创建一个扩展了Java.rmi中远程接口的接口。所有的远程对象必须扩展该远程接口,我们将该远程接口称为AddServer。在该远程对象中,有一个名字为AddNumbers的方法,客户端可以调用这一方法。我们必须记住的是,所有的远程方法都需要启动RemoteException方法,有错误发生时就会调用该方法。下面我们开始编写远程对象的实现。这是一个实现远程对象并包含有所有方法代码的类,将下面的代码保存为名字为AddServerImpl.Java的文件: import Java.rmi.*;public class AddServerImpl extends UnicastRemoteObjec
7、t implements AddServer public AddServerImpl( super(;public int AddNumbers(int firstnumber,int secondnumber throws RemoteException return firstnumber + secondnumber;首先,我们导入rmi包,然后创建一个扩展UnicastRemoteObject和实现创建的远程对象的类;其次,我们可以为类创建一个缺省的构建器。我们还了解了AddNumbers方法的代码,它启动RemoteException。这样我们就覆盖了创建的远程对象中的方法。Add
8、Numbers方法的代码非常好理解,它接受2个整型参数,然后相加并返回它们的和。至此,我们已经有了二个Java文件:远程对象和远程对象的实现。下面我们将使用Javac命令编译这二个文件:编译远程对象:C:jdkbinJavac workingdirAddServer.Java编译远程对象实现:C:jdkbinJavac workingdirAddServerImpl.Java 这样,就会达到二个Java文件和二个类文件,下面我们将创建stub和skeleton。为了创建stub和skeleton文件,我们必须使用rmic编译器编译远程对象实现文件。用Rmic编译远程对象实现文件:C:jdkbi
9、nrmic workingdirAddServerImpl 然后,我们就会发现多了2个新建的类文件,它们分别是AddServerImpl_Stub.class 和AddServerImpl_Skel.class 。我们已经编译了所有的源代码,下面我们来创建客户端和服务器端,将下面的代码保存为名字为RmiServer.Java的文件:import Java.rmi.*;import J.*;public class RmiServer public static void main (String args throws RemoteException, MalformedURLExceptio
10、n AddServerImpl add = new AddServerImpl(;Naming.rebind("addnumbers",add;首先,我们导入Java.rmi包和J包。另外,我们还使用throws从句捕获任何异常。我们从对象中得出远程对象实现,使用rebind方法将字符串addnumbers与该对象绑定。下面的例子显示了绑定的含义:从现在开始,无论何时客户端要调用远程对象,使用字符串addnumbers就可以实现。rebind方法有二个参数:第一个参数是字符串变量,第二个参数是远程对象实现类的对象。下面我们来创建客户端,将下面的代码保存为名字为RmiClie
11、nt.Java的文件:import Java.rmi.*;import J.*;public class RmiClient public static void main(String args throws RemoteException, MalformedURLException String url="rmi://addnumbers"AddServer add;add = (AddServerNaming.lookup(url;int result = add.AddNumbers(10,5;System.out.println(result;
12、首先,我们导入Java.rmi包和J包,并使用throws从句捕获所有必要的异常。然后通过利用Naming类中的静态lookup方法从远程对象中得到一个对象。(这也是我们无需从Naming类中得到一个对象并调用它。而只使用类名字的原因。lookup方法接受远程对象的完整的URL名字,该URL由完整的机器IP地址以及与对象绑定的字符串(也征对象的绑定名组成。在调用远程对象时,我们使用了RMI协议。lookup方法向我们返回一个对象,在能够使用它前,我们必须将它的数据类型转换为与远程对象的数据类型一致。Since we have both our server and client source
13、ready, let's compile them both:至此,我们已经有了服务器端和客户端的源代码,下面我们来编译这二个源文件:编译远程服务器:C:jdkbinJavac workingdirRmiServer.Java编译远程客户端:C:jdkbinJavac workingdirRmiClient.Java在对我们的代码进行测试前,还必须首先启动RMI Registry。RMI Registry 存储有所有绑定的数据,没有它,RMI就不能正常地运行!启动Rmi Registry服务器:C:jdkbinstart rmiregistry我们会注意到,这时会出现一个空白的DOS提
14、示符窗口,这表明Rmi Registry服务器在运行,注意不要关闭该窗口。然后,我们首先在一个DOS提示符窗口中运行Rmi服务器,然后在另一个DOS提示符窗口中运行Rmi客户端。启动RMI服务器:C:jdkbinJava workingdirRmiServer启动RMI客户端:C:jdkbinJava workingdirRmiClient如果一切正常,我们应该能够得到15这个输出。我们向AddNumbers方法输入10和5二个数字,该方法将这二者加起来,并将其和15返回给我们。如果得到了15这个输出,说明我们已经成功地执行了一个远程方法。当然,在这里,我们并没有执行真正意义上的远程方法,因为
15、我们的计算机既是服务器,又是客户机。如果有计算机网络,我们就可以方便地进行执行远程方法的试验了。= =RMI,远程方法调用(Remote Method Invocation是Enterprise JavaBeans 的支柱,是建立分布式Java应用程序的方便途径。RMI是非常容易使用的,但是它非常的强大。RMI的基础是接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子,建立一个简单的远程计算服务和使用它的客户程序一个正常工作的RMI系统由下面几个部分组成:远程服务的接口定义远程服务接口的具体实现Stub 和Skeleton 文件一个运行远程服务的服
16、务器一个RMI命名服务,它允许客户端去发现这个远程服务类文件的提供者(一个HTTP或者FTP服务器一个需要这个远程服务的客户端程序下面我们一步一步建立一个简单的RMI系统。首先在你的机器里建立一个新的文件夹,以便放置我们创建的文件,为了简单起见,我们只使用一个文件夹存放客户端和服务端代码,并且在同一个目录下运行服务端和客户端。如果所有的RMI文件都已经设计好了,那么你需要下面的几个步骤去生成你的系统:1、编写并且编译接口的Java代码2、编写并且编译接口实现的Java代码3、从接口实现类中生成Stub 和Skeleton 类文件4、编写远程服务的主运行程序5、编写RMI的客户端程序6、安装并且
17、运行RMI系统我的程序是在NetBeans IDE 5.5和JDK1.6下编写的,当然运行是在命令提示符下进行的1、接口第一步就是建立和编译服务接口的Java代码。这个接口定义了所有的提供远程服务的功能,在这里我们所有完成的就是加减乘除,下面是源程序:1.package rmiDemo;2./Calculator.java3./define the interface4.import java.rmi.Remote;5.6.public interface Calculator extends Remote7.8.public long add(long a, long b9.throws j
18、ava.rmi.RemoteException;10.11.public long sub(long a, long b12.throws java.rmi.RemoteException;13.14.public long mul(long a, long b15.throws java.rmi.RemoteException;16.17.public long div(long a, long b18.throws java.rmi.RemoteException;19.注意:这个接口继承自Remote,每一个定义的方法都必须抛出一个RemoteException异常对象。建立这个文件,把
19、它存放在刚才的目录下,并且编译。2、接口的具体实现下一步,我们就要写远程服务的具体实现,这是一个CalculatorImpl类文件:1.package rmiDemo;2./CalculatorImpl.java3./Implementation4.import java.rmi.server.UnicastRemoteObject;5.6.public class CalculatorImpl extends UnicastRemoteObject implements Calculator7.8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
20、 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. / 这个实现必须有一个显式的构造函数,并且要抛出一个 RemoteException 异常 public CalculatorImpl( throws java.rmi.RemoteException super(; public long add(long a, long b throws java.rmi.RemoteException return a + b; public long sub(long a, long b throws java.rmi.RemoteExce
21、ption return a - b; public long mul(long a, long b throws java.rmi.RemoteException return a * b; public long div(long a, long b throws java.rmi.RemoteException return a / b; 这个实现类使用了 UnicastRemoteObject 去联接 RMI 系统. 在我们的例子中, 我们是直接的从 UnicastRemoteObject 这个类上继承的, 事实上并不一定要这样 做 , 如 果 一 个 类 不 是 从 UnicastR
22、meoteObject 上 继 承 , 那 必 须 使 用 它 的 exportObject(方法去联接到 RMI. 如果一个类继承自 UnicastRemoteObject,那么它必须提供一个构造函数并 且声明抛出一个 RemoteException 对象.当这个构造函数调用了 super(,它久 激活 UnicastRemoteObject 中的代码完成 RMI 的连接和远程对象的初始化. 3,Stubs 和 Skeletons 下一步就是要使用 RMI 编译器 rmic 来生成桩和框架文件,这个编译运行在 远程服务实现类文件上. 在 IDE 中 build 所有程序 >rmic r
23、miDemoCalculatorImpl 在你的目录下运行上面的命令,成功执行完上面的命令你可以发现一个 Calculator_stub.class 文件,如果你是使用的 Java2SDK,那么你还可以发现 Calculator_Skel.class 文件. 4,主机服务器 远程 RMI 服务必须是在一个服务器中运行的.CalculatorServer 类是一个 非常简单的服务器. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. package rmiDemo; /CalculatorServer.java
24、import java.rmi.Naming; public class CalculatorServer public CalculatorServer( try Calculator c = new CalculatorImpl(; Naming.rebind("rmi:/localhost:1099/CalculatorService", c; catch (Exception e System.out.println("Trouble: " + e; public static void main(String args new Calculat
25、orServer(; 5,客户端 客户端源代码如下: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. package rmiDemo; /CalculatorClient.java import java.rmi.Naming; import java.rmi.RemoteException; import .MalformedURLException; import java.rmi.NotBoundException; public class CalculatorClient public static void main(String ar
26、gs try Calculator c = (Calculator Naming.lookup( 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. "rmi:/localhost /CalculatorService" System.out.println( c.sub(4, 3 ; System.out.println( c.add(4, 5 ;
27、 System.out.println( c.mul(3, 6 ; System.out.println( c.div(9, 3 ; catch (MalformedURLException murle System.out.println(; System.out.println( "MalformedURLException" System.out.println(murle; catch (RemoteException re System.out.println(; System.out.println( "RemoteException" Sy
28、stem.out.println(re; catch (NotBoundException nbe System.out.println(; System.out.println( "NotBoundException" System.out.println(nbe; catch ( java.lang.ArithmeticException ae System.out.println(; System.out.println( "java.lang.ArithmeticException" System.out.println(ae; 保存这个客户端程序到你的目录下 (注意这个目录是一开始建立那个, 所有的我们的文 件都在那个目录下 . 在 IDE 中 build 所有程序. 6,运行 RMI 系统 , 现在我们建立了所有运行这个简单 RM
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小学心理统计思维2025年说课稿
- 上海工商职业技术学院《安装工程基础知识》2025-2026学年第一学期期末试卷(B卷)
- 上海工商职业技术学院《安全心理学》2025-2026学年第一学期期末试卷(A卷)
- 上海工商职业技术学院《Android 应用程序开发》2025-2026学年第一学期期末试卷(A卷)
- 跌倒压疮的护理干预与效果评价
- 3.7 一元线性回归说课稿2025学年中职基础课-下册-劳保版(第七版)-(数学)-51
- 上饶卫生健康职业学院《ARM 嵌入式系统》2025-2026学年第一学期期末试卷(B卷)
- 上海音乐学院《安全评估分析》2025-2026学年第一学期期末试卷(B卷)
- 上海音乐学院《安全人机工程学》2025-2026学年第一学期期末试卷(B卷)
- 上海音乐学院《Access 数据库程序设计》2025-2026学年第一学期期末试卷(B卷)
- 2026广东深圳市优才人力资源有限公司招聘编外聘用人员(派遣至布吉街道)38人笔试备考题库及答案解析
- 2026年北京燕山区中考一模英语模拟试卷试题(含答案详解)
- 2026年音乐歌曲创作技巧考核题库试卷
- 2026年临沂职业学院公开招聘教师人员(13名)笔试参考题库及答案详解
- 2024人教版七年级英语下册 Unit5 Here and now教案
- 2026江苏盐城市交通运输综合行政执法支队招录政府购买服务用工人员2人笔试备考题库及答案详解
- 危险化学品安全知识竞赛考试题库及答案
- 2026年深圳市盐田区初三二模英语试卷(含答案)
- 热电联产行业绿色工厂评价指标体系-地方标准格式审查稿
- 《电化学储能电站建设项目文件收集与档案管理规范》
- 中考作文指导:任务驱动型作文
评论
0/150
提交评论