要編寫(xiě)Java的RMI應(yīng)用程序,必須遵循以下步驟:
遠(yuǎn)程接口提供特定遠(yuǎn)程對(duì)象的所有方法的描述。客戶端可與此遠(yuǎn)程接口進(jìn)行通信。
創(chuàng)建遠(yuǎn)程接口 -
RemoteException
的異常。 以下是遠(yuǎn)程接口的示例。首先定義一個(gè)名為Hello
的接口,此接口有一個(gè)名為printMsg()
的方法。
import java.rmi.Remote;
import java.rmi.RemoteException;
// Creating Remote interface for our application
public interface Hello extends Remote {
void printMsg() throws RemoteException;
}
我們需要實(shí)現(xiàn)在前面的步驟中創(chuàng)建的遠(yuǎn)程接口??梢詥为?dú)寫(xiě)一個(gè)實(shí)現(xiàn)類(lèi),也可以直接使服務(wù)器程序?qū)崿F(xiàn)這個(gè)接口。
開(kāi)發(fā)一個(gè)實(shí)現(xiàn)類(lèi) -
以下是一個(gè)實(shí)現(xiàn)類(lèi)。 在這里,我們創(chuàng)建了一個(gè)名為ImplExample
的類(lèi),并實(shí)現(xiàn)了在上一步中創(chuàng)建的接口Hello
,并提供了打印消息 - printMsg()
方法的具體實(shí)現(xiàn)。
// Implementing the remote interface
public class ImplExample implements Hello {
// Implementing the interface method
public void printMsg() {
System.out.println("This is an example RMI program");
}
}
RMI服務(wù)器程序應(yīng)實(shí)現(xiàn)遠(yuǎn)程接口或擴(kuò)展實(shí)現(xiàn)類(lèi)。在這里,我們應(yīng)該創(chuàng)建一個(gè)遠(yuǎn)程對(duì)象并將其綁定到RMIregistry
。
開(kāi)發(fā)服務(wù)器程序 -
java.rmi.server
中的UnicastRemoteObject
類(lèi)的exportObject()
方法導(dǎo)出遠(yuǎn)程對(duì)象。java.rmi.registry
包中的LocateRegistry
類(lèi)的getRegistry()
方法獲取RMI注冊(cè)表。Registry
類(lèi)的bind()方法將創(chuàng)建的遠(yuǎn)程對(duì)象綁定到注冊(cè)表。對(duì)于此方法,傳遞表示綁定名稱(chēng)和導(dǎo)出的對(duì)象的字符串作為參數(shù)。對(duì)于此方法,需要傳遞一個(gè)表示綁定名稱(chēng)的字符串值作為參數(shù)。這將返回遠(yuǎn)程對(duì)象。以下是RMI服務(wù)器程序的示例,創(chuàng)建一名為:Server.java的文件保存以下代碼 -
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends ImplExample {
public Server() {}
public static void main(String args[]) {
try {
// Instantiating the implementation class
ImplExample obj = new ImplExample();
// Exporting the object of implementation class
// (here we are exporting the remote object to the stub)
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Binding the remote object (stub) in the registry
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
在這里我們編寫(xiě)一個(gè)客戶端程序,獲取遠(yuǎn)程對(duì)象并使用此對(duì)象調(diào)用所需的方法。
要開(kāi)發(fā)客戶端程序,請(qǐng)參考以下步驟 -
java.rmi.registry
包中的LocateRegistry
類(lèi)的getRegistry()
方法獲取RMI注冊(cè)表。java.rmi.registry
包中的Registry
類(lèi)的lookup()
方法從注冊(cè)表獲取對(duì)象。lookup()
返回一個(gè)類(lèi)型為remote
的對(duì)象,將其轉(zhuǎn)換為Hello
類(lèi)型。以下是RMI客戶端程序的示例,創(chuàng)建一個(gè)名稱(chēng)為:Client.java 的文件 -
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
try {
// Getting the registry
Registry registry = LocateRegistry.getRegistry(null);
// Looking up the registry for the remote object
Hello stub = (Hello) registry.lookup("Hello");
// Calling the remote method using the obtained object
stub.printMsg();
// System.out.println("Remote method invoked");
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
編譯應(yīng)用程序 -
或者 -
打開(kāi)存儲(chǔ)所有程序的文件夾,使用以下命令編譯所有Java文件,如下所示 -
javac *.java
執(zhí)行結(jié)果如下 -
第一步 - 使用以下命令啟動(dòng)rmi注冊(cè)表。
start rmiregistry
這將在單獨(dú)的窗口中啟動(dòng)一個(gè)rmi注冊(cè)表,如下所示。
第二步 - 運(yùn)行服務(wù)器類(lèi)文件,如下所示。
java Server
打開(kāi)另一個(gè)命令行提示符,執(zhí)行上面命令,如下所示 -
第三步 - 運(yùn)行客戶端類(lèi)文件,如下所示。
java Client
打開(kāi)另一個(gè)命令行提示符,執(zhí)行上面命令,如下所示 -
驗(yàn)證遠(yuǎn)程調(diào)用結(jié)果 - 當(dāng)啟動(dòng)客戶端后,將在服務(wù)器中看到以下輸出。