RMI网络编程

Java RMI

维基百科
 
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。

Java RMI极大地依赖于接口。在需要创建一个远程对象的时候,程序员通过传递一个接口来隐藏底层的实现细节。客户端得到的远程对象句柄正好与本地的根代码连接,由后者负责透过网络通信。这样一来,程序员只需关心如何通过自己的接口句柄发送消息。

socket是两台主机之间的一个连接,而JAVA中的SOCKET类为不同主机之间的连接提供了功能封装。

所以,SOCKET是进程间通信的一种常用方法。

RMI是sun开发,遵循JRMP协议,因为他被发布在jre中,所有很多人只把它当作很普通的api来使用,所以它里面做了什么,很多人都不清楚.

RMI到底是什么?

  • RMI是一套足够优秀的socket框架.
  • RMI是相对比较简单命名服务
  • RMI是aop的经典实用例子
  • 相关辅助功能,比如本地GC

总之,RMI也是一个重要的通信手段。

这里讲述的是基于JDK1.5的RMI程序搭建,更简单的说是一个 HelloWorld RMI。

1. 这里是基于JDK1.5的,节省了繁琐的手工编译(生成桩和骨架)。不像1.4之前的RMI。

2. 这里是把客户端和服务器端的两个程序,分布在两个独立的程序里面,而不是同一个package下面。是真正的分布式。

3. 这里不过多阐述原理,这只是一个Hello World!!

好,以下是步骤:

1. 在Eclipse里面创建一个server 端的project。然后,创建一个接口,这个接口是你要向client端开放的方法定义。它叫做:UserManagerInterface,而且必须继承Remote接口。

  1. package dataserver.rmi.stub; 
  2.  
  3. import java.rmi.Remote; 
  4. import java.rmi.RemoteException; 
  5.  
  6. import dataserver.rmi.bean.Account; 
  7.  
  8. public interface UserManagerInterface extends Remote{ 
  9.     public String getUserName() throws RemoteException; 
  10.     public Account getAdminAccount() throws RemoteException; 

2. 为了证明RMI中,“面向对象”或者是“无缝传递JAVA Object”是何等简单,我们需要定义一个Account类,该类是一个Bean,必须实现implements Serializable序列化接口。这是一个可以在client和server传输的可序列化对象。

  1. package dataserver.rmi.bean; 
  2.  
  3. import java.io.Serializable; 
  4.  
  5. public class Account implements Serializable,Cloneable{ 
  6.  
  7.     /** 
  8.      *  
  9.      */ 
  10.     private static final long serialVersionUID = -1858518369668584532L; 
  11.     private String username; 
  12.     private String password; 
  13.      
  14.     public String getUsername() { 
  15.         return username; 
  16.     } 
  17.     public void setUsername(String username) { 
  18.         this.username = username; 
  19.     } 
  20.     public String getPassword() { 
  21.         return password; 
  22.     } 
  23.     public void setPassword(String password) { 
  24.         this.password = password; 
  25.     } 
  26.      

3. 此时,需要实现你已经开放的接口:

  1. package dataserver.rmi; 
  2.  
  3. import java.rmi.RemoteException; 
  4.  
  5. import dataserver.rmi.bean.Account; 
  6. import dataserver.rmi.stub.UserManagerInterface; 
  7.  
  8. public class UserManagerImpl implements UserManagerInterface { 
  9.  
  10.     public UserManagerImpl() throws RemoteException { 
  11.         //super(); 
  12.         // TODO Auto-generated constructor stub 
  13.         //UnicastRemoteObject.exportObject(this); 
  14.     } 
  15.  
  16.     /** 
  17.      *  
  18.      */ 
  19.     private static final long serialVersionUID = -3111492742628447261L; 
  20.  
  21.     public String getUserName() throws RemoteException { 
  22.         // TODO Auto-generated method stub 
  23.         return "Tommy Lee"
  24.     } 
  25.  
  26.     public Account getAdminAccount() throws RemoteException { 
  27.         // TODO Auto-generated method stub 
  28.         Account account=new Account(); 
  29.         account.setUsername("admin"); 
  30.         account.setPassword("admin"); 
  31.         return account; 
  32.     } 
  33.  

4. 定义一个主程序入口,注册你已经实现的RMI接口,包括开放端口等。其实很简单:

把我们的接口名称,命名为“userManager”,方便client进行调用

  1. package dataserver.entry; 
  2.  
  3. import java.rmi.AlreadyBoundException; 
  4. import java.rmi.RemoteException; 
  5. import java.rmi.registry.LocateRegistry; 
  6. import java.rmi.registry.Registry; 
  7. import java.rmi.server.UnicastRemoteObject; 
  8. import java.util.concurrent.TimeUnit;
  9.  
  10. import dataserver.rmi.UserManagerImpl; 
  11. import dataserver.rmi.stub.UserManagerInterface; 
  12.  
  13. public class Entry { 
  14.  
  15.     public static void main(String []args) throws AlreadyBoundException, RemoteException{ 
  16.      
  17.  
  18.             UserManagerImpl userManager=new UserManagerImpl(); 
  19.             UserManagerInterface userManagerI=(UserManagerInterface)UnicastRemoteObject.exportObject(userManager,0); 
  20.             // Bind the remote object's stub in the registry 
  21.             Registry registry = LocateRegistry.createRegistry(2001); 
  22.             registry.rebind("userManager", userManagerI); 
  23.             System.out.println("server is ready"); 
  24.             TimeUnit.SECONDS.sleep(5);
  25.     } 

5. Server端的代码已经全部写完,但是还要把bean类(Account)和接口类(UserMangerInterface)打包成jar,以便可以在下面导入进client端的项目中。

项目--》右键--》导出--》jar--》选择bean和interface--》命名为RmiServerInterface.jar--》finish

6.  开始创建client端的程序。新建一个project。创建完成后,把刚才jar包导入进client的项目中。

7.  导入我们的接口jar以后,可以开始编写一个client端的主程序,并调用server端的方法。

  1. package weiblog.rmi; 
  2. import java.rmi.NotBoundException; 
  3. import java.rmi.RemoteException; 
  4. import java.rmi.registry.LocateRegistry; 
  5. import java.rmi.registry.Registry; 
  6.  
  7. import dataserver.rmi.stub.UserManagerInterface; 
  8.  
  9. public class Entry2 { 
  10.  
  11.     public static void main(String []args){ 
  12.          
  13.         try { 
  14.             Registry registry = LocateRegistry.getRegistry("localhost",2001); 
  15.             UserManagerInterface userManager = (UserManagerInterface) registry.lookup("userManager"); 
  16.             System.out.println(""+userManager.getAdminAccount().getUsername() 
  17.                     +userManager.getAdminAccount().getPassword()); 
  18.         } catch (RemoteException e) { 
  19.             // TODO Auto-generated catch block 
  20.             e.printStackTrace(); 
  21.         } catch (NotBoundException e) { 
  22.             // TODO Auto-generated catch block 
  23.             e.printStackTrace(); 
  24.         } 
  25.          
  26.     } 

8. 启动server端的主程序,然后启动client端的主程序。

server控制台打印:server is ready

client控制台打印:adminadmin

本文出自 “JAVAWeb开发” 博客,请务必保留此出处http://6221123.blog.51cto.com/6211123/1111871

原文地址:https://www.cnblogs.com/CanWork/p/3735886.html