分享

小湖~

 ShangShujie 2006-11-15
演练 Java RMI
 
 —— 小湖java笔记之(七)
 

Java RMI(Remote Method Invocation, RMI)为采用Java对象的分布式计算提供了简单而直接的途径。是纯java实现的应用通信机制。当然相比CORBA,RMI功能较弱且只能用于Java系统。假期回家期间,通过设计一个实例进行实战演练,终于对使用RMI的过程有了具体的认识。现将步骤和实例相应代码整理如下:

1.定义远程接口中的参数和返回值类型。必须保证其可以被序列化。这点往往被很多人忽视。 RMI规范其中很重要一点就是要求远程接口中的参数(返回值)应实现序列化。因为需要将客户端的对象(参数)转化成byte stream,传输到服务端后还原成服务端的对象进行调用。或者是需要将服务端的对象(返回值)转化成byte stream,传输到客户端还原成客户端的对象进行调用。当然,基本数据类型以及String,数组等都已经是可序列化的。在演习的例子中,参数等都比较简单,没有涉及到这个步骤。(顺便查阅了不少关于序列化的文章,相关内容将另成一篇。)
 
2.定义一个远程接口,该接口继承java.rmi.Remote,同时定义了所有将被远程调用的方法。这些方法必须抛出 RemoteException 异常。
 
WeatherForecastRemote.java:
 
package com.xiaohu_studio.weatherforecast;
import java.rmi.*;
public interface WeatherForecastRemote extends Remote {
    String  WFToday() throws RemoteException;
    String  WFTomorrow() throws RemoteException;
}

 
3.定义一个继承于java.rmi.UnicastRemoteObject且实现上述接口的类。将要被远程调用的对象就是这个类的对象。要注意的是,必须要有最少一个显式的构造函数。构造函数必须抛出RemoteException异常。
 
WeatherForecast.java:
 
package com.xiaohu_studio.weatherforecast;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class WeatherForecast extends UnicastRemoteObject implements
                 WeatherForecastRemote {
     static String[] description={"Sunny","Cloudy","Rainy","Windy"};
 
     public WeatherForecast() throws RemoteException {}
 
     public String WFToday() throws RemoteException {
          return description[(int)(Math.random()*4)];
     }
 
     public String WFTomorrow() throws RemoteException {
         return description[(int)(Math.random()*4)];
     }
}

 
4.编写服务端代码,创建和安装一个安全性管道,并注册远程对象。发现可以忽略安装安全性管道。如果安装的话,必须创建一个安全策略文件,否则会出现AccessControlException。客户端也一样。
 
WeatherForecastServer.java
 
package com.xiaohu_studio.weatherforecast;
import java.rmi.*;
import java.rmi.registry.*;
//import java.rmi.server.*;
//import java.net.*;
public class WeatherForecastServer {
    public static void main(String[] args) {
        if (System.getSecurityManager() == null) {
             System.out.println("Set Security Manager.");
             System.setSecurityManager(new RMISecurityManager());
        }
        try {
             WeatherForecast wf=new WeatherForecast();
             LocateRegistry.createRegistry(8898); // 注册端口
             Naming.bind("rmi://127.0.0.1:8898/wf",wf);   
        } catch (Exception e) {
             System.out.print("Error---- "+e.toString());
             e.printStackTrace();
        }
    }
 
}

安全策略文件policy.txt:
 
grant {
    permission java.security.AllPermission;
    //Allow everything for now
};
 
(步骤3和4可以合并成一个类。)
 
5.编写客户端代码,创建和安装一个安全性管道,查找远程对象,并调用远程方法
 
WeatherForecastClient.java:
 
package com.xiaohu_studio.weatherforecast;
import java.rmi.*;
public class WeatherForecastClient {
  public static void main(String[] args) {
     if (System.getSecurityManager() == null) {
          System.out.println("Set Security Manager.");
          System.setSecurityManager(new RMISecurityManager()); 
     }
     try {
          WeatherForecastRemote ff;
          //System.out.println("Lookup the Remote object.");
          ff=(WeatherForecastRemote)Naming.lookup("rmi://127.0.0.1:8898/wf");
          //注意是WeatherForecastRemote,而不是WeatherForecast,否则抛出ClassCastException.
         System.out.print("Today‘s weahter: ");
         System.out .println(ff.WFToday());
         System.out.print("Tomorrow‘s weather: ");
         System.out .println(ff.WFTomorrow());
     } catch (Exception e){
         System.out.println("Error:"+e.toString());
     }
  }
}
6.生成stub和skeltion ,并将stub打包到客户端jar中,将skeltion打包到服务端jar中。
在演习的例子的时候,发现用直接mic命令(不带参数)只生成_Stub.class,将该_Stub.class同时打包到客户端和服务端即可。
 
rmic com.xiaohu_studio.weatherforecast.WeatherForecast
(如果需要生成_Slel.calss,则需用rmic -vcompat 命令)
 
7.用命令 rmiregistry 命令来启动RMI注册服务。
在命令行输入命令 :
start rmiregistry 8898

如果在服务端代码中包含了启动RMI注册服务的代码(LocateRegistry.createRegistry(8808);),则可以省略该步骤。
 
8.运行服务端及客户端代码。
 服务端文件:(目录:d:\server\com\xiaohu_studio\weatherforecast)
 policy.txt
  WeatherForecastRemote.class
  WeatherForecast.class
  WeatherForecastServer.class
  WeatherForecast_Stub.class
  服务端运行命令:(目录:d:\client\com\xiaohu_studio\weatherforecast)
 java -Djava.security.policy=com\xiaohu_studio\weatherforecast\policy.txt com.xiaohu_studio.weatherforecast.WeatherForecastServer 
 
 客户端文件:
 policy.txt
  WeatherForecastRemote.class
  WeatherForecast_Stub.class
  客户端运行命令:
 java -Djava.security.policy=com\xiaohu_studio\weatherforecast\policy.txt com.xiaohu_studio.weatherforecast.WeatherForecastClient

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多