演練 Java RMI
—— 小湖java筆記之(七)
Java RMI(Remote Method Invocation, RMI)為采用Java對(duì)象的分布式計(jì)算提供了簡(jiǎn)單而直接的途徑。是純java實(shí)現(xiàn)的應(yīng)用通信機(jī)制。當(dāng)然相比CORBA,RMI功能較弱且只能用于Java系統(tǒng)。假期回家期間,通過(guò)設(shè)計(jì)一個(gè)實(shí)例進(jìn)行實(shí)戰(zhàn)演練,終于對(duì)使用RMI的過(guò)程有了具體的認(rèn)識(shí)。現(xiàn)將步驟和實(shí)例相應(yīng)代碼整理如下: 1.定義遠(yuǎn)程接口中的參數(shù)和返回值類型。必須保證其可以被序列化。這點(diǎn)往往被很多人忽視。 RMI規(guī)范其中很重要一點(diǎn)就是要求遠(yuǎn)程接口中的參數(shù)(返回值)應(yīng)實(shí)現(xiàn)序列化。因?yàn)樾枰獙⒖蛻舳说膶?duì)象(參數(shù))轉(zhuǎn)化成byte stream,傳輸?shù)椒?wù)端后還原成服務(wù)端的對(duì)象進(jìn)行調(diào)用?;蛘呤切枰獙⒎?wù)端的對(duì)象(返回值)轉(zhuǎn)化成byte stream,傳輸?shù)娇蛻舳诉€原成客戶端的對(duì)象進(jìn)行調(diào)用。當(dāng)然,基本數(shù)據(jù)類型以及String,數(shù)組等都已經(jīng)是可序列化的。在演習(xí)的例子中,參數(shù)等都比較簡(jiǎn)單,沒有涉及到這個(gè)步驟。(順便查閱了不少關(guān)于序列化的文章,相關(guān)內(nèi)容將另成一篇。) 2.定義一個(gè)遠(yuǎn)程接口,該接口繼承java.rmi.Remote,同時(shí)定義了所有將被遠(yuǎn)程調(diào)用的方法。這些方法必須拋出 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.定義一個(gè)繼承于java.rmi.UnicastRemoteObject且實(shí)現(xiàn)上述接口的類。將要被遠(yuǎn)程調(diào)用的對(duì)象就是這個(gè)類的對(duì)象。要注意的是,必須要有最少一個(gè)顯式的構(gòu)造函數(shù)。構(gòu)造函數(shù)必須拋出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.編寫服務(wù)端代碼,創(chuàng)建和安裝一個(gè)安全性管道,并注冊(cè)遠(yuǎn)程對(duì)象。發(fā)現(xiàn)可以忽略安裝安全性管道。如果安裝的話,必須創(chuàng)建一個(gè)安全策略文件,否則會(huì)出現(xiàn)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); // 注冊(cè)端口 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可以合并成一個(gè)類。)
5.編寫客戶端代碼,創(chuàng)建和安裝一個(gè)安全性管道,查找遠(yuǎn)程對(duì)象,并調(diào)用遠(yuǎn)程方法
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打包到服務(wù)端jar中。
在演習(xí)的例子的時(shí)候,發(fā)現(xiàn)用直接mic命令(不帶參數(shù))只生成_Stub.class,將該_Stub.class同時(shí)打包到客戶端和服務(wù)端即可。
rmic com.xiaohu_studio.weatherforecast.WeatherForecast
(如果需要生成_Slel.calss,則需用rmic -vcompat 命令)
7.用命令 rmiregistry 命令來(lái)啟動(dòng)RMI注冊(cè)服務(wù)。
在命令行輸入命令 :
start rmiregistry 8898 如果在服務(wù)端代碼中包含了啟動(dòng)RMI注冊(cè)服務(wù)的代碼(LocateRegistry.createRegistry(8808);),則可以省略該步驟。 8.運(yùn)行服務(wù)端及客戶端代碼。
服務(wù)端文件:(目錄:d:\server\com\xiaohu_studio\weatherforecast) policy.txt WeatherForecastRemote.class WeatherForecast.class WeatherForecastServer.class WeatherForecast_Stub.class 服務(wù)端運(yùn)行命令:(目錄: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 客戶端運(yùn)行命令:
java -Djava.security.policy=com\xiaohu_studio\weatherforecast\policy.txt com.xiaohu_studio.weatherforecast.WeatherForecastClient |
|
來(lái)自: ShangShujie > 《java》