談笑有鴻儒,往來無白丁

          在恰當(dāng)?shù)臅r(shí)間、地點(diǎn)以恰當(dāng)?shù)姆绞奖磉_(dá)給恰當(dāng)?shù)娜?..  閱讀的時(shí)候請(qǐng)注意分類,佛曰我日里面是談笑文章,其他是各個(gè)分類的文章,積極的熱情投入到寫博的隊(duì)伍中來,支持blogjava做大做強(qiáng)!向dudu站長(zhǎng)致敬>> > 我的微博敬請(qǐng)收聽
          本篇用實(shí)例來說明采用Java進(jìn)行RMI遠(yuǎn)程方法調(diào)用的實(shí)現(xiàn)方法,從而為分布應(yīng)用軟件的開發(fā)者提供參考和幫助。
            Internet/Intranet的飛速發(fā)展使得Web應(yīng)用日益廣泛而復(fù)雜,Web早已不僅僅是超媒體信息的瀏覽工具,它正逐步發(fā)展成為分布異構(gòu)環(huán)境中企業(yè)應(yīng)用的通用前端和事務(wù)處理的展現(xiàn)窗口。在分布式環(huán)境異構(gòu)中,各種機(jī)器所采用的操作系統(tǒng)、網(wǎng)絡(luò)通信協(xié)議和應(yīng)用軟件千差萬別,要實(shí)現(xiàn)信息共享和軟件資源的整合十分困難,然而一個(gè)健壯的分布式計(jì)算框架能為可移植的分布式應(yīng)用軟件開發(fā)帶來巨大的便利和好處。
            分布式對(duì)象技術(shù)主要是在分布式異構(gòu)環(huán)境下建立應(yīng)用系統(tǒng)框架和對(duì)象構(gòu)件。在應(yīng)用系統(tǒng)框架的支撐下,開發(fā)者可以將軟件功能封裝為更易管理和使用的對(duì)象,這些對(duì)象可以跨越不同的軟、硬件平臺(tái)進(jìn)行互操作。目前,分布式互操作標(biāo)準(zhǔn)主要有Microsoft的COM/DCOM標(biāo)準(zhǔn)、Sun公司的Java RMI標(biāo)準(zhǔn)和OMG組織的CORBA標(biāo)準(zhǔn)。
            Java RMI調(diào)用實(shí)例
            Java RMI簡(jiǎn)介
            遠(yuǎn)程方法調(diào)用(RMI,Remote Method Invocation)是jdk1.1中引入的分布式對(duì)象軟件包,它的出現(xiàn)大大簡(jiǎn)化了分布異構(gòu)環(huán)境中Java應(yīng)用之間的通信。
            
            要使用RMI,必須構(gòu)建四個(gè)主要的類:遠(yuǎn)程對(duì)象的本地接口、遠(yuǎn)程對(duì)象實(shí)現(xiàn)、RMI客戶機(jī)和RMI服務(wù)器。RMI服務(wù)器生成遠(yuǎn)程對(duì)象實(shí)現(xiàn)的一個(gè)實(shí)例,并用一個(gè)專有的URL注冊(cè)。RMI客戶機(jī)在遠(yuǎn)程RMI服務(wù)器上查找服務(wù)對(duì)象,并將它轉(zhuǎn)換成本地接口類型,然后像對(duì)待一個(gè)本地對(duì)象一樣使用它。
            
            下面是一個(gè)簡(jiǎn)單的RMI實(shí)例,RMI客戶機(jī)通過RMI服務(wù)器提供的方法實(shí)現(xiàn)對(duì)兩個(gè)雙精度浮點(diǎn)數(shù)的加減運(yùn)算。例子雖然很簡(jiǎn)單,但掌握了Java RMI調(diào)用的基本原理和方法,在實(shí)現(xiàn)復(fù)雜應(yīng)用時(shí),我們需要做的也只是完善遠(yuǎn)程對(duì)象的實(shí)現(xiàn)類而已。
            
            RMI實(shí)例分析
            
            1.遠(yuǎn)程對(duì)象的本地接口聲明(RMIOperate.java)
            
            該類僅僅是一個(gè)接口聲明,RMI客戶機(jī)可以直接使用它,RMI服務(wù)器必須通過一個(gè)遠(yuǎn)程對(duì)象來實(shí)現(xiàn)它,并用某個(gè)專有的URL注冊(cè)它的一個(gè)實(shí)例。
            
            具體代碼如下:
            
            package wf.rmi; //包名
            import java.rmi.*; //導(dǎo)入類包
            /*RMI本地接口必須從Remote接口派生*/
             public interface RMIOperate extends Remote
            {
             /*接口中的具體方法聲明,注意必須聲明拋出RemoteException*/
             public double add(double x, double y) throws RemoteException;
            //輸入兩個(gè)浮點(diǎn)數(shù),返回其和
             public double minus(double x, double y) throws RemoteException;
            //輸入兩個(gè)浮點(diǎn)數(shù),返回其差
            }
            2.遠(yuǎn)程對(duì)象實(shí)現(xiàn)類(OperateImpl.java)
            這個(gè)類應(yīng)實(shí)現(xiàn)RMI客戶機(jī)調(diào)用的遠(yuǎn)程服務(wù)對(duì)象的本地接口,它必須從UnicastRemoteObject繼承,構(gòu)造函數(shù)應(yīng)拋出RemoteException異常。
            具體代碼如下:
            
            package wf.rmi; //包名
            //導(dǎo)入需要的類包
            import java.rmi.*;
            import wf.rmi.RMIOperate;
            import java.rmi.server.UnicastRemoteObject;
            public class OperateImpl extends UnicastRemoteObject implements RMIOperate
            {
             /*構(gòu)造函數(shù)*/
             public OperateImpl() throws RemoteException
             {
             }
             /*實(shí)現(xiàn)本地接口中聲明的add方法*/
             public double add(double x, double y) throws RemoteException
             {
             double z = x + y;
             return z;
             }
             /*實(shí)現(xiàn)本地接口中聲明的minus方法*/
             public double minus(double x, double y) throws RemoteException
             {
             double z = x - y;
             return z;
             }
            }
            3.RMI服務(wù)器類(RMIServer.java)
            該類創(chuàng)建遠(yuǎn)程對(duì)象實(shí)現(xiàn)類OperateImpl的一個(gè)實(shí)例,然后通過一個(gè)專有的URL來注冊(cè)它。所謂注冊(cè)就是通過Java.rmi.Naming.bind()方法或Java.rmi.Naming.rebind()方法,將OperateImpl實(shí)例綁定到指定的URL上。
            
            具體實(shí)現(xiàn)代碼如下:
            
            package wf.rmi; //包名
            //導(dǎo)入需要的類包
            import java.rmi.Naming;
            import wf.rmi.OperateImpl;
            public class RMIServer
            {
             public static void main(String[] args)
             {
             try
             {
              //創(chuàng)建遠(yuǎn)程對(duì)象的實(shí)現(xiàn)實(shí)例
              OperateImpl operObj = new OperateImpl();
              //提示信息
              System.out.println("RMI Server Starting...");
              //將實(shí)例注冊(cè)到專有的URL
              Naming.rebind("rmi:///RMIOperate", operObj);
              //等待RMI客戶機(jī)調(diào)用的提示信息
              System.out.println("Waiting RMI Client Invoke...");
             }
             catch(Exception e)
             {
              e.printStackTrace();
             }
             }
            }
            4.RMI客戶機(jī)類(RMIClient.java)
            
            RMI客戶使用java.rmi.Naming.lookup()方法,在指定的遠(yuǎn)程主機(jī)上查找RMI服務(wù)對(duì)象,若找到就把它轉(zhuǎn)換成本地接口RMIOperate類型。它與CORBA不同之處在于RMI客戶機(jī)必須知道提供RMI服務(wù)主機(jī)的URL,這個(gè)URL可以通過rmi://host/path或rmi://host:port/path來指定,如果省略端口號(hào),就默認(rèn)使用1099。Java.rmi.Naming.lookup()方法可能產(chǎn)生三個(gè)異常:Java.rmi.RemoteException、Java.rmi.NotBoundException、java.net. MalformedURLException,三個(gè)異常都需要捕獲。
            
            下面是詳細(xì)代碼:
            
            package wf.rmi; //包名
            //導(dǎo)入需要的類包
            import java.rmi.*;
            import java.net.*;
            import java.io.*;
            public class RMIClient
            {
              public static void main(String[] args)
              {
                try
                {
                  BufferedReader readIn = new BufferedReader(new
            InputStreamReader(System.in));
                  String host = "localhost"; //默認(rèn)為本地主機(jī)
             //帶輸入?yún)?shù)時(shí),將host設(shè)置為指定主機(jī)
                  if (args.length > 0)
                    host = args[0];
                  //根據(jù)指定的URL定位遠(yuǎn)程實(shí)現(xiàn)對(duì)象
            RMIOperate rmiObj = (RMIOperate)Naming.lookup("rmi://" + host +
            "/RMIOperate");      //提示輸入運(yùn)算參數(shù)1
            System.out.println("Please Input Data1: ");
                  String str1 = readIn.readLine(); //讀取輸入?yún)?shù)1
                  double x = 0;
                  try
                  {
               x = Double.parseDouble(str1); //分析輸入?yún)?shù)1,轉(zhuǎn)換為double類型
                  }
                 catch(NumberFormatException nfe)
                  {
                    x = 0; //如果轉(zhuǎn)換異常,則重置x為0
                  }
             //提示輸入運(yùn)算參數(shù)2
                  System.out.println("Please Input Data2: ");
                  String str2 = readIn.readLine();//讀取輸入?yún)?shù)2
                  double y = 0;
                  try
                  {
                    y = Double.parseDouble(str2); //分析輸入?yún)?shù)2,轉(zhuǎn)換為double類型
                  }
                  catch(NumberFormatException nfe)
                  {
                    y = 0; //如果轉(zhuǎn)換異常,則重置y為0
                  }
             //調(diào)用遠(yuǎn)程對(duì)象的本地接口方法,實(shí)現(xiàn)輸入?yún)?shù)的加、減運(yùn)算,并輸出結(jié)果
                 System.out.println("Data1 Add Data2 Result is: " + rmiObj.add(x, y));
                 System.out.println("Data1 minus Data2 Result is: " +
              rmiObj.minus(x, y));
                }
                catch(Exception e)
                {
                  e.printStackTrace();
                }
              }
            }
            RMI Server/Client的編譯與運(yùn)行
            
            (1).編譯所有的源代碼(如圖1)
             
            圖1
            (2).生成客戶端存根和服務(wù)器框架(如圖2)
             
            圖2
            這將構(gòu)造OperateImpl_Stub.class和OperateImpl_Skel.class。這時(shí)可將所有的Class文件打包成jar,并將其分別置于RMI客戶機(jī)和RMI服務(wù)器的ClassPath中(如圖3):
             
            圖3
            當(dāng)然,也可以只將RMIOperate.class、RMIClient.class和OperateImpl_Stub.class復(fù)制到RMI客戶機(jī),將RMIOperate.class、OperateImpl.class 、RMIServer.class和OperateImpl_Skel.class復(fù)制到RMI服務(wù)器。
            (3).啟動(dòng)RMI注冊(cè)(如圖4)
             
            圖4
            (4).運(yùn)行和調(diào)用
            ● 在服務(wù)器上執(zhí)行RMIServer(如圖5)
             
            圖5
            ● 在本地客戶機(jī)上運(yùn)行RMIClient(如圖6)
             
            圖6
            ● 在遠(yuǎn)程客戶機(jī)上運(yùn)行RMIClient(須指明RMI服務(wù)器主機(jī)名或IP地址,如圖7)
             
            圖7
            至此,RMI調(diào)用完成。

          ??????? 摘自:http://youngyj1982.bokee.com/
          posted on 2006-12-31 14:18 壞男孩 閱讀(1046) 評(píng)論(0)  編輯  收藏 所屬分類: java命令學(xué)習(xí)
          主站蜘蛛池模板: 永州市| 改则县| 图们市| 柯坪县| 克什克腾旗| 昔阳县| 应用必备| 莆田市| 砀山县| 随州市| 青田县| 平南县| 鸡西市| 达尔| 濮阳市| 辽阳县| 临漳县| 华池县| 永丰县| 来安县| 三都| 通城县| 榆林市| 平定县| 恩施市| 连州市| 贡觉县| 井陉县| 紫阳县| 吴川市| 湖南省| 伊春市| 赤城县| 承德县| 夏河县| 腾冲县| 临湘市| 怀宁县| 三都| 罗田县| 邓州市|