基礎教程之——RMI一步一步學習

          RMI,遠程方法調用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java應用程序的方便途徑。RMI是非常容易使用的,但是它非常的強大。
            RMI的基礎是接口,RMI構架基于一個重要的原理:定義接口和定義接口的具體實現是分開的。下面我們通過具體的例子,建立一個簡單的遠程計算服務和使用它的客戶程序

            一個正常工作的RMI系統由下面幾個部分組成:
          1、  編寫并且編譯接口的Java代碼
            2、  編寫并且編譯接口實現的Java代碼
            3、  從接口實現類中生成 Stub 和 Skeleton 類文件
            4、  編寫遠程服務的主運行程序
            5、  編寫RMI的客戶端程序
            6、  安裝并且運行RMI系統

            1、接口

            第一步就是建立和編譯服務接口的Java代碼。這個接口定義了所有的提供遠程服務的功能,下面是源程序:

          1. //Calculator.java
          2. //define the interface
          3. import java.rmi.Remote;
          4. public interface Calculator extends Remote
          5. {
          6.     public long add(long a, long b) 
          7.         throws java.rmi.RemoteException
          8.     public long sub(long a, long b) 
          9.         throws java.rmi.RemoteException
          10.     public long mul(long a, long b) 
          11.         throws java.rmi.RemoteException
          12.     public long div(long a, long b) 
          13.         throws java.rmi.RemoteException

            注意,這個接口繼承自Remote,每一個定義的方法都必須拋出一個RemoteException異常對象。

            建立這個文件,把它存放在剛才的目錄下,并且編譯。

            >javac Calculator.java

            2、接口的具體實現

            下一步,我們就要寫遠程服務的具體實現,這是一個CalculatorImpl類文件:

          1. //CalculatorImpl.java
          2. //Implementation
          3. import java.rmi.server.UnicastRemoteObject;
          4. public class CalculatorImpl extends UnicastRemoteObject implements Calculator 
          5.     // 這個實現必須有一個顯式的構造函數,并且要拋出一個RemoteException異常 
          6.     public CalculatorImpl() 
          7.         throws java.rmi.RemoteException { 
          8.         super(); 
          9.     } 
          10.     public long add(long a, long b) 
          11.         throws java.rmi.RemoteException { 
          12.         return a + b; 
          13.     } 
          14.     public long sub(long a, long b) 
          15.         throws java.rmi.RemoteException { 
          16.         return a - b; 
          17.     } 
          18.     public long mul(long a, long b) 
          19.         throws java.rmi.RemoteException { 
          20.         return a * b; 
          21.     } 
          22.     public long div(long a, long b) 
          23.         throws java.rmi.RemoteException { 
          24.         return a / b; 
          25.     } 

            同樣的,把這個文件保存在你的目錄里然后編譯他。

            這個實現類使用了UnicastRemoteObject去聯接RMI系統。在我們的例子中,我們是直接的從UnicastRemoteObject這個類上繼承的,事實上并不一定要這樣做,如果一個類不是從UnicastRmeoteObject上繼承,那必須使用它的exportObject()方法去聯接到RMI。

            如果一個類繼承自UnicastRemoteObject,那么它必須提供一個構造函數并且聲明拋出一個RemoteException對象。當這個構造函數調用了super(),它久激活UnicastRemoteObject中的代碼完成RMI的連接和遠程對象的初始化。

            3、Stubs 和Skeletons

            下一步就是要使用RMI編譯器rmic來生成樁和框架文件,這個編譯運行在遠程服務實現類文件上。

            >rmic CalculatorImpl

            在你的目錄下運行上面的命令,成功執行完上面的命令你可以發現一個Calculator_stub.class文件,如果你是使用的Java2SDK,那么你還可以發現Calculator_Skel.class文件。

            4、主機服務器

            遠程RMI服務必須是在一個服務器中運行的。CalculatorServer類是一個非常簡單的服務器。

          1. //CalculatorServer.java
          2. import java.rmi.Naming;
          3. public class CalculatorServer {
          4.    public CalculatorServer() {
          5.      try {
          6.        Calculator c = new CalculatorImpl();
          7.        Naming.rebind("rmi://localhost:1099/CalculatorService", c);
          8.      } catch (Exception e) {
          9.        System.out.println("Trouble: " + e);
          10.      }
          11.    }
          12.    public static void main(String args[]) {
          13.      new CalculatorServer();
          14.    }
          15. }

            建立這個服務器程序,然后保存到你的目錄下,并且編譯它。

            5、客戶端

            客戶端源代碼如下:

          1. //CalculatorClient.java
          2. import java.rmi.Naming
          3. import java.rmi.RemoteException
          4. import java.net.MalformedURLException
          5. import java.rmi.NotBoundException
          6. public class CalculatorClient { 
          7.     public static void main(String[] args) { 
          8.         try { 
          9.             Calculator c = (Calculator)
          10.                            Naming.lookup(
          11.                  "rmi://localhost
          12.                         /CalculatorService"); 
          13.             System.out.println( c.sub(4, 3) ); 
          14.             System.out.println( c.add(4, 5) ); 
          15.             System.out.println( c.mul(3, 6) ); 
          16.             System.out.println( c.div(9, 3) ); 
          17.         } 
          18.         catch (MalformedURLException murle) { 
          19.             System.out.println(); 
          20.             System.out.println(
          21.               "MalformedURLException"); 
          22.             System.out.println(murle); 
          23.         } 
          24.         catch (RemoteException re) { 
          25.             System.out.println(); 
          26.             System.out.println(
          27.                         "RemoteException"); 
          28.             System.out.println(re); 
          29.         } 
          30.         catch (NotBoundException nbe) { 
          31.             System.out.println(); 
          32.             System.out.println(
          33.                        "NotBoundException"); 
          34.             System.out.println(nbe); 
          35.         } 
          36.         catch (
          37.             java.lang.ArithmeticException
          38.                                       ae) { 
          39.             System.out.println(); 
          40.             System.out.println(
          41.              "java.lang.ArithmeticException"); 
          42.             System.out.println(ae); 
          43.         } 
          44.     } 
            保存這個客戶端程序到你的目錄下(注意這個目錄是一開始建立那個,所有的我們的文件都在那個目錄下),并且編譯他。

            6、運行RMI系統

            現在我們建立了所有運行這個簡單RMI系統所需的文件,現在我們終于可以運行這個RMI系統啦!來享受吧。

            我們是在命令控制臺下運行這個系統的,你必須開啟三個控制臺窗口,一個運行服務器,一個運行客戶端,還有一個運行RMIRegistry。

            首先運行注冊程序RMIRegistry,你必須在包含你剛寫的類的那么目錄下運行這個注冊程序。

            >rmiregistry

            好,這個命令成功的話,注冊程序已經開始運行了,不要管他,現在切換到另外一個控制臺,在第二個控制臺里,我們運行服務器CalculatorService,因為RMI的安全機制將在服務端發生作用,所以你必須增加一條安全策略。以下是對應安全策略的例子 
          grant {
          permission java.security.AllPermission "", "";
          };

            注意:這是一條最簡單的安全策略,它允許任何人做任何事,對于你的更加關鍵性的應用,你必須指定更加詳細安全策略。

            現在為了運行服務端,你需要除客戶類(CalculatorClient.class)之外的所有的類文件。確認安全策略在policy.txt文件之后,使用如下命令來運行服務器。

            > java -Djava.security.policy=policy.txt CalculatorServer

            這個服務器就開始工作了,把接口的實現加載到內存等待客戶端的聯接。好現在切換到第三個控制臺,啟動我們的客戶端。

            為了在其他的機器運行客戶端程序你需要一個遠程接口(Calculator.class) 和一個stub(CalculatorImpl_Stub.class)。 使用如下命令運行客戶端

             > java -Djava.security.policy=policy.txt CalculatorClient

            如果所有的這些都成功運行,你應該看到下面的輸出:
            1
            9
            18
            3

            如果你看到了上面的輸出,恭喜你,你成功了,你已經成功的創建了一個RMI系統,并且使他正確工作了。即使你運行在同一個計算機上,RMI還是使用了你的網絡堆棧和TCP/IP去進行通訊,并且是運行在三個不同的Java虛擬機上。這已經是一個完整的RMI系統。

          posted on 2007-07-03 16:16 bc 閱讀(54) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿

          隨筆檔案

          文章檔案

          搜索

          最新評論

          主站蜘蛛池模板: 尤溪县| 沁阳市| 洪洞县| 伊春市| 南投县| 合江县| 射洪县| 固安县| 永福县| 牡丹江市| 台江县| 安溪县| 益阳市| 介休市| 罗平县| 巧家县| 镇巴县| 昌都县| 射洪县| 碌曲县| 秦安县| 株洲县| 遵义县| 饶平县| 南丹县| 开化县| 武乡县| 寻甸| 西宁市| 武陟县| 赣州市| 新竹市| 崇信县| 新余市| 康马县| 衡水市| 开封县| 墨竹工卡县| 仁寿县| 黎城县| 武夷山市|