JAVA RMI远程方法调用简单实例

简介:

RMI的概念

RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。使用这种机制,某一台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据。RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote Procedure Call)应运而生,它使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持,而且RPC未能做到面向对象调用的开发模式。针对RPC服务遗留的问题,RMI出现在世人面前,它被设计成一种面向对象的通讯方式,允许程序员使用远程对象来实现通信,并且支持多线程的服务,这是一次远程通讯的革命,为远程通信开辟新的里程碑。

RMI的开发步骤

  1. 先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote
  2. 开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject
  3. 通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象
  4. 最后客户端查找远程对象,并调用远程方法

简单实例

首先为服务建立一个Model层,注意因为此对象需要现实进行远程传输,所以必须继承Serializable

 

  1.  
  2. package rmi.model; 
  3.  
  4. import java.io.Serializable; 
  5.  
  6. //注意对象必须继承Serializable 
  7. public class PersonEntity implements Serializable { 
  8.     private int id; 
  9.     private String name; 
  10.     private int age; 
  11.  
  12.     public void setId(int id) { 
  13.         this.id = id; 
  14.     } 
  15.  
  16.     public int getId() { 
  17.         return id; 
  18.     } 
  19.  
  20.     public void setName(String name) { 
  21.         this.name = name; 
  22.     } 
  23.  
  24.     public String getName() { 
  25.         return name; 
  26.     } 
  27.  
  28.     public void setAge(int age) { 
  29.         this.age = age; 
  30.     } 
  31.  
  32.     public int getAge() { 
  33.         return age; 
  34.     } 

创建远程接口PersonService,注意远程接口需要继承Remote

 
  1. package rmi.service; 
  2.  
  3. import java.rmi.Remote; 
  4. import java.rmi.RemoteException; 
  5. import java.util.List; 
  6. import rmi.model.*; 
  7.  
  8. //此为远程对象调用的接口,必须继承Remote类 
  9. public interface PersonService extends Remote { 
  10.     public List<PersonEntity> GetList() throws RemoteException; 

建立PersonServiceImpl实现远程接口,注意此为远程对象实现类,需要继承UnicastRemoteObject

 
  1. package rmi.serviceImpl; 
  2.  
  3. import java.rmi.RemoteException; 
  4. import java.rmi.server.UnicastRemoteObject; 
  5. import java.util.LinkedList; 
  6. import java.util.List; 
  7.  
  8. import rmi.model.PersonEntity; 
  9. import rmi.service.*; 
  10.  
  11. //此为远程对象的实现类,须继承UnicastRemoteObject 
  12. public class PersonServiceImpl extends UnicastRemoteObject implements PersonService { 
  13.  
  14.     public PersonServiceImpl() throws RemoteException { 
  15.         super(); 
  16.         // TODO Auto-generated constructor stub 
  17.     } 
  18.  
  19.     @Override 
  20.     public List<PersonEntity> GetList() throws RemoteException { 
  21.         // TODO Auto-generated method stub 
  22.         System.out.println("Get Person Start!"); 
  23.         List<PersonEntity> personList=new LinkedList<PersonEntity>(); 
  24.          
  25.         PersonEntity person1=new PersonEntity(); 
  26.         person1.setAge(25); 
  27.         person1.setId(0); 
  28.         person1.setName("Leslie"); 
  29.         personList.add(person1); 
  30.          
  31.         PersonEntity person2=new PersonEntity(); 
  32.         person2.setAge(25); 
  33.         person2.setId(1); 
  34.         person2.setName("Rose"); 
  35.         personList.add(person2); 
  36.          
  37.         return personList; 
  38.     }     

建立服务器端,在服务器端注册RMI通讯端口与通讯路径,然后通讯javac命令编译文件,通过java -server 命令注册服务。以下面代码为例,如果阁下将项目建立于D:\\RMI\RemotingService文件夹上时,则先输入D:\\RMI\RemotingService\src>javac rmi/remotingservice/Program.java获取Program.class(如何阁下使用的MyEclipse等开发工具,可跳过此步,直接在*/bin文件夹中直接调用已经生成的Program.class),然后输入D:\\RMI\RemotingService\src>java rmi/remotingservice/Program启动服务。

 
  1. package rmi.remotingservice; 
  2.  
  3. import java.rmi.Naming; 
  4. import java.rmi.registry.LocateRegistry; 
  5.   
  6. import rmi.service.*; 
  7. import rmi.serviceImpl.*; 
  8.  
  9. public class Program{ 
  10.  
  11.     public static void main(String[] args) { 
  12.         try { 
  13.             PersonService personService=new PersonServiceImpl(); 
  14.             //注册通讯端口 
  15.             LocateRegistry.createRegistry(6600); 
  16.             //注册通讯路径 
  17.             Naming.rebind("rmi://127.0.0.1:6600/PersonService", personService); 
  18.             System.out.println("Service Start!"); 
  19.         } catch (Exception e) { 
  20.             // TODO Auto-generated catch block 
  21.             e.printStackTrace(); 
  22.         } 
  23.     } 

最后建立客户端进行测试,注意客户调用的RMI路径必须服务器配置一致

 
  1. package rmi.remotingclient; 
  2.  
  3. import java.rmi.Naming; 
  4. import java.util.List; 
  5.  
  6. import rmi.model.PersonEntity; 
  7. import rmi.service.*; 
  8.  
  9. public class Program { 
  10.     public static void main(String[] args){ 
  11.         try
  12.             //调用远程对象,注意RMI路径与接口必须与服务器配置一致 
  13.             PersonService personService=(PersonService)Naming.lookup("rmi://127.0.0.1:6600/PersonService"); 
  14.             List<PersonEntity> personList=personService.GetList(); 
  15.             for(PersonEntity person:personList){ 
  16.                 System.out.println("ID:"+person.getId()+" Age:"+person.getAge()+" Name:"+person.getName()); 
  17.             } 
  18.         }catch(Exception ex){ 
  19.             ex.printStackTrace(); 
  20.         } 
  21.     } 

常见错误

  1. 在命令提示符调用java命令时,显示并无此命令。这是因为未在“环境变量”中绑定JAVA的JDK命令造成的,你首先单击“计算机右键”->“属性”->“高级”->“环境变量”。在系统变量Path设置中加载为JDK的路径  .;D:\Program Files\Genuitec\Common\binary\com.sun.java.jdk.win32.x86_1.6.0.013\bin。然后在ClassPath加载服务器端的Program.class地址 .;D:\\RMI\RemotingService\bin
  2. 在调用javac命令时出现“javac 找不到文件 ..... ”此错误,可能是因为阁下输入的文件路径出现错误造成,注意不要把D:\\RMI\RemotingService\src>javac rmi/remotingservice/Program.java写错为D:\\RMI\RemotingService\src>javac rmi.remotingservice.Program.java
  3. 在调用D:\\RMI\RemotingService\bin>java rmi/remotingservice/Program命令时出现“Exception in thread 'main' java.lang.NoClassEdfoundError”错误,第一这可能是阁下把Program错写为Program.class,注意java命令不需要加后缀名。第二可能是阁下把“java rmi/remotingservice/Program”错写为“java rmi\remotingservice\Program"。

原代码下载
 

远程对象相互调用相关文章:

回顾.NET Remoting分布式开发

JAVA RMI远程方法调用简单实例

利用JNBridge桥接模式实现远程通讯

对.NET Remoting开发有兴趣的的朋友欢迎加入QQ群:162338858 点击这里加入此群



本文转自 leslies2  51CTO博客,原文链接:

http://blog.51cto.com/79100812/844062

相关文章
|
1月前
|
Java 程序员
Java 异常处理与正则表达式详解,实例演练及最佳实践
在 Java 代码执行期间,可能会发生各种错误,包括程序员编码错误、用户输入错误以及其他不可预料的状况。 当错误发生时,Java 通常会停止并生成错误消息,这个过程称为抛出异常。 try...catch 语句 try 语句允许您定义一段代码块,并在其中测试是否发生错误。 catch 语句允许您定义一段代码块,当 try 块中发生错误时执行该代码块。 try 和 catch 关键字成对使用,语法如下:
42 0
|
4月前
|
人工智能 Java 5G
常见的Java内存溢出情况和实例
常见的Java内存溢出情况和实例
|
1月前
|
存储 Java
Java 编程实例:相加数字、计算单词数、字符串反转、元素求和、矩形面积及奇偶判断
Java中相加两个数字可通过简单赋值实现,如`int sum = x + y;`。若要用户输入数字相加,可使用`Scanner`类读取。计算单词数,可使用`split()`方法或`StringTokenizer`类。反转字符串,可用`for`循环或`StringBuilder`的`reverse()`方法。计算数组元素总和,可遍历数组累加。矩形面积通过长度乘以宽度得出。判断奇偶性,利用模2运算或位运算检查最低位。更多内容,可关注微信公众号`Let us Coding`。
49 0
|
4月前
|
存储 Java 编译器
【Java变量】 局部变量、成员变量(类变量,实例变量)、方法参数传递机制
【Java变量】 局部变量、成员变量(类变量,实例变量)、方法参数传递机制
41 0
|
4月前
|
机器学习/深度学习 存储 JavaScript
正则表达式基础语法与Java、JS使用实例
正则表达式基础语法与Java、JS使用实例
72 1
|
1月前
|
Java
java面向对象高级分层实例_实体类
java面向对象高级分层实例_实体类
10 1
|
12天前
|
Java Shell
Java 21颠覆传统:未命名类与实例Main方法的编码变革
Java 21颠覆传统:未命名类与实例Main方法的编码变革
13 0
|
4月前
|
Java
Java | 类、实例初始化 、方法重写规则
Java | 类、实例初始化 、方法重写规则
25 0
|
1月前
|
Java
java面向对象高级分层实例_测试类(main方法所在的类)
java面向对象高级分层实例_测试类(main方法所在的类)
10 1
|
1月前
|
Java 数据库
java面向对象高级分层实例_数据库操作类
java面向对象高级分层实例_数据库操作类
11 1