1. 程式人生 > >java遠端呼叫介面的原理和範例

java遠端呼叫介面的原理和範例

Java 遠端處理 
   Java遠端方法呼叫(RMI)提供了Java程式語言的遠端通訊功能,這種特性使客戶機上執行的程式可以呼叫遠端伺服器上的物件,使Java程式設計人員能夠在網路環境中分佈操作。
   建立一個簡單的Java分散式遠端方法呼叫程式可以按以下幾個步驟操作,
  
   一、定義遠端介面:
   在 Java 中,遠端物件是實現遠端介面的類的例項, 遠端介面宣告每個要遠端呼叫的方法。在需要建立一個遠端物件的時候,我們通過傳遞一個介面來隱藏基層的實施細節,客戶通過介面控制代碼傳送訊息即可。
   遠端介面具有如下特點:
   1) 遠端介面必須為public屬性。如果不這樣,除非客戶端與遠端介面在同一個包內,否則 當試圖裝入實現該遠端介面的遠端物件時,呼叫會得到錯誤結果。
   2) 遠端介面必須擴充套件介面java.rmi.Remote。
   3) 除與應用程式本身特定的例外之外,遠端介面中的每個方法都必須在自己的throws從句中 宣告java.rmi.RemoteException。(或 RemoteException 的父類)。
   4) 作為引數或返回值傳遞的一個遠端物件(不管是直接,還是本地物件中嵌入)必須宣告為遠 程介面,而不應宣告為實施類。

下面是遠端介面的定義

[java] view plaincopy
package test;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.math.BigInteger;

public interface Fib extends Remote {
public int getFib(int n) throws RemoteException;
// public BigInteger getFib(BigInteger n) throws RemoteException;
}

二、實現遠端介面:
   遠端物件實現類必須擴充套件遠端物件java.rmi.UnicastRemoteObject類,並實現所定義的遠端介面。遠端物件的實現類中包含實現每個遠端介面所指定的遠端方法的程式碼。這個類也可以含有附加的方法,但客戶只能使用遠端介面中的方法。因為客戶是指向介面的一個控制代碼,而不是它的哪個類。必須為遠端物件定義建構函式,即使只准備定義一個
預設建構函式
,用它呼叫基礎類建構函式。因為基礎類建構函式可能會丟擲 java.rmi.RemoteException,所以即使別無它用必須丟擲java.rmi.RemoteException例外。
   以下是遠端物件實現類的宣告:

[java] view plaincopy
package test;
import java.math.BigInteger;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

public class FibImp extends UnicastRemoteObject implements Fib {
public FibImp() throws RemoteException {
super();
}

public int getFib(int n) throws RemoteException {
return n+2;
}

}

三、編寫伺服器類:
   包含 main 方法的類可以是實現類自身,也可以完全是另一個類。下面通過RmiSampleServer 來建立一個遠端物件的例項,並通過java.rmi.registry.LocateRegistry類的createRegistry 方法從指定埠號啟動註冊服務程式,也可以通過執行 rmiregistry 命令啟動註冊服務程式,註冊服務程式的預設執行埠為 1099。必須將遠端物件名字繫結到對遠端物件的引用上: Naming.rebind("//localhost:8808/SAMPLE-SERVER" , Server);
   以下是伺服器類的宣告:

[java] view plaincopy
package test;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class FibonacciServer {
/**
* @param args
*/
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(8804);
FibImp f = new FibImp();

// 註冊到 registry 中
Naming.rebind("//localhost:8804/SAMPLE-SERVER", f);
System.out.println("fib server ready");

} catch (RemoteException re) {
System.out.println("Exception in FibonacciImpl.main: " + re);
} catch (MalformedURLException e) {
System.out.println("MalformedURLException " + e);
}
}
}

四、編寫使用遠端服務的客戶機類:
   客戶機類的主要功能有兩個,一是通過Naming.lookup方法來構造註冊服務程式 stub 程式例項,二是呼叫伺服器遠端物件上的遠端方法。
   以下是客戶端類的宣告:

[java] view plaincopy
package testClient;

import test.Fib;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class FibClient {
/**
* @param args
*/
public static void main(String[] args) {
String url = "//localhost:8804/SAMPLE-SERVER";
try {

Fib calc = (Fib) Naming.lookup(url);
for (int i = 0; i < 10; ++i) {
int f = calc.getFib(i);
System.out.println(f);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}