Applet與Servlet之間的聯系一般是間接的,即頁面請求由浏覽器發送給Servlet,作為回答,Servlet將結果生成HTML文檔發送給浏覽器。很多時候在Servlet與Applet之間建立直接的聯系是沒有必要的,但如果要顯示一些實時的動態數據,如聊天室窗口、新聞顯示、股市行情等,建立兩者之間的直接聯系就很有用了。特別地,在較為復雜的分布式Java應用中,這種通訊更是必不可少。在客戶端Java程序與服務器端Java程序之間建立這種復雜的交互方式僅僅使用Servlet與Applet API是不夠的,本文為你介紹和比較四種通訊方式:通過HTML頁面傳遞參數,用java.net包的網絡功能建立直接網絡連接,遠程方法調用(RMI)與CORBA。
一、通過HTML頁面傳遞Applet參數
通過HTML頁面傳遞參數是在Servlet與Applet之間建立聯系最為常用的方法。Servlet只要把傳遞給Applet的參數寫入HTML頁面就可以了。這種通訊是單向的,用於實現Servlet對Applet的控制。其實現方法類如:
// doGet()方法生成一個包含Applet的HTML頁面,
// 該Applet需要一個Data參數
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = new PrintWriter ( response.getOutputStream());
out.write("< HTML>< HEAD>< TITLE> HTML Example< /TITLE> < /HEAD>< BODY>");
out.write("Servlet通過PARAM標記傳遞參數給Applet. ");
out.write("< APPLET code=\"SimpleApplet\" width=\"225\" height=\"149\">");
// 寫入PARAM標記
out.write("< param name=\"Data\" value=\"");
out.write(java.text.DateFormat.getDateInstance().format(new java.util.Date()));
out.write("\">< /APPLET>< /BODY>< /HTML>");
out.close();
}
這種方法很簡單,但它有兩個缺點。首先,所有參數都是靜態的,即一旦HTML頁面發送完成,要更新其中部分數據就很困難了。雖然可以使用HTTP的刷新機制,但這種刷新需要重新下載整個頁面,效率是很低的。第二,如果需要傳遞給Applet的數據量很大或數據結構很復雜,就會使得HTML頁面過於龐大或復雜了。
二、用java.net包建立雙向通訊
第二種方法是利用java.net包提供的網絡能力。以有連接流通訊方式為例,在服務器端的操作為一般為:
⑴ 創建一個ServerSocket對象,在指定端口監聽客戶端發來的請求。
⑵ 在接收到請求時accept()方法將返回一個Socket對象。
⑶ 用上述Socket對象創建輸入、輸出流對象。
⑷ 通過輸入、輸出流與客戶交互。
⑸ 交互完畢,關閉輸入、輸出流與Socket。
⑹ 服務程序運行結束,關閉ServerSocket。
實現代碼代碼類如:
try{
boolean flag=true;
Socket clientSocket=null;
ServerSocket serverSocket = new ServerSocket(0);
System.out.println("Server listen on: " +serverSocket.getLocalPort());
while(flag){
clientSocket=serverSocket.accept();
DataInputStream is=new DataInputStream( new bufferedInputStream(clientSocket.getInputStream()));
PrintStream os=new PrintStream( new bufferedOutputStream(clientSocket.getOutputStream()));
// 處理Applet請求
os.close();
is.close();
clientSocket.close();
}
serverSocket.close();
}catch( IOException e){
System.err.println(" Exception: "+e);
}
在客戶端的操作為:
⑴ 創建Socket對象建立與服務器的連接。
⑵ 用該Socket對象創建輸入、輸出流。
⑶ 與服務器交互。
⑷ 交互完畢,關閉輸入、輸出流與Socket。
實現代碼類如:
try {
Socket clientSocket =new Socket("serverName",7);
OutputStream os=clientSocket.getOutputStream();
DataInputStream is=new DataInputStream( clientSocket.getInputStream());
// 其它操作.
os.close();
is.close();
clientSocket.close();
}catch(Exception e){
System.err.println("Exception:"+e);
}
這種方法只依賴於標准的Java網絡支持,不需要用到附加的軟件包或工具, 因此顯得相當簡潔和靈活,易於實現某些特殊的需要。但在另一方面,服務器端對進入請求以及客戶端對返回結果的分析工作量較大。如果服務器端要執行大量的操作,可以考慮使用RMI。