第十一篇 RMI远程方法调用之Java项目实例

来源:互联网 发布:node cpu used 编辑:程序博客网 时间:2024/05/22 23:27
      上一篇我们简单的介绍了一下RMI。这篇文章中我们针对JAVA做一个RMI的Java项目实例,供大家参考。
创建远程方法调用的5个步骤:
1、创建一个Java项目
2、定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。
3、定义一个实现该接口的类。
4、编写服务器程序代码。
5、创建一个客户程序与服务器进行RMI调用。
6、启动Registry并运行自己的远程服务器和客户程序
第一步、创建一个Java项目名叫RMIServer
     对于如何创建一个Java项目这里不详细说明。
     项目的架构如下图:

第二步、定义远程接口
    在Java 中,远程对象是实现远程接口的类的实例, 远程接口声明每个要远程调用的方法。在需要创建一个远程对象的时候,我们通过传递一个接口来隐藏基层的实施细节,客户通过接口句柄发送消息即可。 远程接口具有如下特点:
   1) 远程接口必须为public属性。如果不这样,除非客户端与远程接口在同一个包内,否则 当试图装入实现该远程接口的远程对象时,调用会得到错误结果。
   2) 远程接口必须扩展接口java.rmi.Remote。
   3) 除与应用程序本身特定的例外之外,远程接口中的每个方法都必须在自己的throws从句中 声明java.rmi.RemoteException。(或 RemoteException 的父类)。
   4) 作为参数或返回值传递的一个远程对象(不管是直接,还是本地对象中嵌入)必须声明为远 程接口,而不应声明为实施类。
创建一个RMI程序首先要做的就是创建一个扩展远程接口的接口。在这个接口中可以添加任意希望能在远程机器上调用的方法。
接口示例
public interface UserManagerInterface extends Remote{
     public String getUserName() throws RemoteException;
     public UserPO getUser() throws RemoteException;
}
在接口中定义了一个返回字符串userName的方法和返回一个UserPO对象的,其中本地接口(UserManagerInterface)必须是公共的,否则客户机在加载一个实现该接口的远程对象时就会出错。它必须从java.rmi.Remote继承而来,接口中的每一个方法都必须抛出远程异常java.rmi.RemoteException。抛出这个异常的原因由于任何远程方法调用实际上要进行许多低级网络操作,因此网络错误可能在调用过程中随时发生。因此,所有的RMI操作都应放到try-catch块中。
第三步、定义一个实现该接口的类。
远程对象实现类必须扩展远程对象java.rmi.UnicastRemoteObject类,并实现所定义的远程接口。远程对象的实现类中包含实现每个远程接口所指定的远程方法的代码。这个类也可以含有附加的方法,但客户只能使用远程接口中的方法。因为客户是指向接口的一个句柄,而不是它的哪个类。必须为远程对象定义构造函数,即使只准备定义一个默认构造函数,用它调用基础类构造函数。因为基础类构造函数可能会抛出 java.rmi.RemoteException,所以即使别无它用必须抛出java.rmi.RemoteException例外。
 以下是远程对象实现类的声明:

public class UserManagerImpl implements UserManagerInterface {

 public UserManagerImpl() throws RemoteException {
 }
 public String getUserName() throws RemoteException {
  return "RMI测试用户";
 }
 public UserPO getUser() throws RemoteException {
  UserPO userPO=new UserPO();
  userPO.setUsername("RMI测试用户");
  userPO.setPassword("pwd");
  System.out.println("返回userPO");
  return userPO;
 }
}

第四步、编写服务器类:
下面通过RmiSampleServer创建一个远程对象的实例,并通过java.rmi.registry.LocateRegistry类的createRegistry 方法从指定端口号启动注册服务程序,也可以通过执行 rmiregistry 命令启动注册服务程序,注册服务程序的缺省运行端口为 1099。必须将远程对象名字绑定到对远程对象的引用上: Naming.rebind("//localhost:8808/SAMPLE-SERVER" , Server);
    以下是服务器类的声明:

public static void main(String []args) throws AlreadyBoundException, RemoteException{
  UserManagerImpl userManager=new UserManagerImpl();
  UserManagerInterface userManagerI=(UserManagerInterface)UnicastRemoteObject.exportObject(userManager,0);
     Registry registry = LocateRegistry.createRegistry(2001);
     registry.rebind("userManater", userManagerI);
  System.out.println("server is ready")

 }

第五步、编写服务器程序代码进行RMI调用
 客户机类的主要功能有两个,一是通过Naming.lookup方法来构造注册服务程序 stub 程序实例,二是调用服务器远程对象上的远程方法。
  以下是服务器类的声明:
public class Client {
 public static void main(String []args) {
  try {
   Registry registry = LocateRegistry.getRegistry(null,2001);//如果第一个参数为空的话,默认为localhost
      UserManagerInterface userManager = (UserManagerInterface) registry.lookup("userManater");
      /** 
       * 如果服务端使用
       * LocateRegistry.createRegistry(8808);   
         UserManagerImpl server= new UserManagerImpl();    
          Naming.rebind("//localhost:8808/rmitest" , server);
       * 在客户端可以用如下方法获取
       * String url ="//localhost:8808/rmitest";   
       * UserManagerImpl userManagerImpl = (UserManagerImpl) Naming.lookup(url);
       * System.out.println(userManagerImpl.getUserName());  
      */
      System.out.println(userManager.getUserName());
  } catch (RemoteException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NotBoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}
注意:请停留在客户端代码上看一下注释中的内容,当我们使用注释里面的方法的时候,UserManagerImpl必须实现接口Serializable,声明该对象可序列化,同时在使用上述服务端方法的时候,会抛出异常java.net.MalformedURLException,可以将异常抛出也可以将异常捕获,看自己具体实现。

因为我们的客户端和服务器在同一个项目中,因为我们在实际应用中,几乎不可能出现服务器端和客户端在同一个项目中,在这里我们需要做的就是,将客户端的接口类以jar包的形式导出,然后在服务端项目中将导出的jar包导入项目路径,在这里就不将客户端和服务端分开了,如果读者想这样的的话,可以按如下步骤:

 A.新建JAVA项目

B.然后将Client类拷入新建的项目中。同时需要将导出的jar包导入项目路径中即可。导出jar包很简单,为了照顾大多数初学者,在这里说一下导出jar包的方法

项目--》右键--》导出--》jar--》选择要导出的类》命名为xxx.jar--》finish

 

到现在我们的RMI  Java项目已经创建完成,那我们看一下如何运行该程序。

首先将Server.java文件右击 >>run as >>Java Application将服务端启动。然后再客户端上以同样的方法运行,即可看到效果。

到现在此篇文章也该结束了,和大家分享一下eclipse里面的一个RMI开发的一个插件,自己刚安装完,并没有开始使用,有兴趣的可以下来研究一下。该插件下载地址为是【ttp://www.genady.net/rmi/v20/downloads.html】。至于该项目源码可以到本人的CSDN空间中去下载名称为rmi_Java项目实例。谢谢大家支持。