使用 Dojo 工具包和 JSON-RPC 構建企業 SOA Ajax 客戶端

CloudSpace發表於2008-08-25

瞭解如何使用 Dojo 工具包為 Java™ Platform. Extended Edition (Java EE) 應用程式構建企業 SOA 客戶端,以及如何使用 JavaScript. Object Notation–RPC (JSON-RPC) 來呼叫伺服器端 Java 物件。

引言

非同步 JavaScript. 和 XML (Ajax) 是使用本機瀏覽器技術構建富 Web 應用程式的新方法。對於編寫需要某些型別的“活動”使用者介面的複雜應用程式的開發人員,JavaScript. 在這方面已經做得很好。不過,JavaScript. 難於編碼、除錯、移植和維護。使用 Ajax 工具包有助於最大程度地減少使用 JavaScript. 和 Ajax 帶來的許多常見問題。優秀的 Ajax 工具包提供了一組可重用的小部件、用於擴充套件和建立小部件的框架、事件系統、JavaScript. 實用工具和增強的非同步伺服器呼叫支援。在本文中,我們將討論如何使用 Dojo 工具包為 Java EE 應用程式構建企業 SOA 客戶端。我們還將使用 JSON (JavaScript. Object Notation)–RPC 來呼叫伺服器端 Java 物件。

在本文中,我們還將向您提供以下內容的簡要說明:Ajax、Dojo、JSON 和 JSON-RPC,以及一些設計 Ajax 應用程式的設計原則和您可以下載並親自嘗試執行的簡短示例。

Ajax 概述

有許多關於 Ajax 的論文、文章和書籍。我不打算對 Ajax 進行深入介紹。有關詳細資訊,請查閱參考資料

Ajax 可作為使用本機瀏覽器元件構建網站的體系結構樣式。Ajax 的關鍵部分有:

  • JavaScript,它可以編排頁面元素,從而獲得最佳 Ajax 使用者體驗。
  • Cascading Style. Sheets (CSS),它可以定義頁面元素的可視樣式。
  • 文件物件模型(Document Object Model,DOM),它將網頁結構作為一組可以使用 JavaScript. 操作的可程式設計物件提供。
  • XMLHttpRequest,它支援以後臺活動的形式從 Web 資源檢索資料。

XMLHttpRequest 物件是關鍵部分。

XMLHttpRequest 物件

XMLHttpRequest 物件是 Ajax 用於進行非同步請求的機制。圖 1 說明了該流程:


圖 1. XMLHttpRequest 物件進行非同步請求的流程圖
XMLHttpRequest 物件進行非同步請求的流程圖。

XMLHttpRequest 物件是瀏覽器中提供的 JavaScript. 物件。(Microsoft™ 和 Mozilla 瀏覽器各有自已的版本)。該流程如下所示:

  1. 頁面呼叫某個 JavaScript。
  2. JavaScript. 函式建立 XMLHttpRequest 物件。這包括設定要呼叫的 URL 和 HTTP 請求引數。
  3. JavaScript. 函式註冊回撥處理程式。HTTP 響應呼叫此回撥處理程式。
  4. JavaScript. 函式呼叫 XMLHttpRequest 物件上的 send 方法,該方法接著將 HTTP 請求傳送到伺服器。
  5. XMLHttpRequest 物件立即將控制返回到 JavaScript. 方法。此時,使用者可以繼續使用該頁面。
  6. 稍後,HTTP 伺服器通過呼叫回撥處理程式返回 HTTP 響應。
  7. 回撥處理程式可以訪問 HTML DOM 物件。它可以動態更新頁面元素,而無需中斷使用者(除非您碰巧更新使用者正在使用的 DOM 物件)。

通過非同步更新頁面的 DOM,還可以在本地進行非同步請求。

Dojo 工具包概述

Dojo 使您能夠方便地構建動態站點。它提供一個豐富的小部件庫,您可以使用它組成頁面。您可以使用基於 Dojo 方面的事件系統將事件附加到元件,以建立豐富的互動體驗。此外,您可以使用幾個 Dojo 庫進行非同步伺服器請求、新增動畫效果和瀏覽儲存實用工具等等。

Dojo 小部件

Dojo 提供了您可以用於構建頁面的一組豐富的小部件。您可以使用多個方法建立 Dojo 小部件。Dojo 的眾多優點之一是它允許您使用標準的 HTML 標記。然後,可以將這些標記用於小部件。這樣,HTML 開發人員就可以方便地使用 Dojo,如清單 1 所示:


清單 1. 在 HTML 標記中使用 Dojo
dojoType="FloatingPane" class="stockPane" title="Stock Form" id="pane" constrainToContainer="true" displayMaximizeAction="true">

Stock Service

Enter symbol: dojoType="ValidationTextBox" required="true" id="stockInput">


您可以使用 div 標記來定義小部件的位置,而在頁面載入或對事件進行響應時 Dojo 可以在這些地方放置小部件。您還可以使用更具體的標記,如 ,並向其中新增 Dojo 小部件屬性。在清單 1 中,我們將 dojoType 屬性新增到 button 標記。在設定了標記之後,您需要在一些 JavaScript. 內部載入小部件,如清單 2 所示。您可以將標記嵌入到頁面內部,但是我們建議將其放置在單獨的 JS 檔案中。在本文的稍後部分中,我們將闡明一些 MVC 設計原則。


清單 2. 在 HTML 標記中使用 Dojo
//require statements
dojo.require("dojo.widget.*" );
dojo.require("dojo.event.*");
dojo.require("dojo.widget.Button2");
dojo.require("dojo.widget.FloatingPane" );

//all dojo.require above this line
dojo.hostenv.writeIncludes(); 
dojo.require();	
	

您可以在 JavaScript. 中建立、訪問、修改和刪除小部件,從而實現動態行為。在我們的示例中,您將看到在 JavaScript. 中訪問小部件的示例。

Dojo 事件系統

Dojo 事件系統使用面向方面的技術將事件附加到小部件。這可以將小部件與實際的事件處理分離。Dojo 不是將硬程式碼 JavaScript. 事件新增到 html 標記上,而是提供允許您將事件附加到小部件的 API,如清單 3 所示。


清單 3. 使用 Dojo 將事件處理程式附加到小部件
function submitStock()
	{
		...
	}
function init()
	{
		var stockButton = dojo.widget.byId('stockButton');
		dojo.event.connect(stockButton, 'onClick', 'submitStock');
	}
dojo.addOnLoad(init);
	

通過使用 connect 方法,您可將 JavaScript. 方法連線到小部件。您還可以在 div 節點上附加 dojoAttachEvent,如下所示。某些 HTML 標記沒有定義事件,所以這是一個方便的擴充套件。


清單 4. 使用 Dojo 將事件附加到 HTML 標記
dojoAttachEvent="onClick; onMouseOver: onFoo;">

Dojo 事件系統還允許多個高階功能,如:

  • 宣告在現有的事件處理程式之前或之後插入事件處理程式的建議。
  • 允許小部件在瀏覽器中訂閱或釋出主題。
  • 新增事件回撥。
  • 可用於表示事件的 event 規範化物件。

有關詳細資訊,請參見 http://dojo.jot.com/EventExamples

Dojo 非同步伺服器請求

Dojo 通過抽象特定於瀏覽器的詳細資訊,提供了對伺服器進行非同步請求的簡單方法。Dojo 允許您建立資料結構來隱藏詳細資訊,如清單 5 所示。


清單 5. 使用 Dojo 進行非同步請求
var bindArgs = {
    url:        "/DojoJ2EE/MyURI",
    mimetype:   "text/javascript",
    error:      function(type, errObj){
        // handle error here 
    },
    load:      function(type, data, evt){
        // handle successful response here
    }
};
// dispatch the request
var requestObj = dojo.io.bind(bindArgs);
	

此外,Dojo 使用 JSON-RPC 標準支援 RPC。在接下來的部分中,我們將看一看 Dojo 對 JSON 的支援。

附加的 Dojo 功能

Dojo 是一個具有許多功能的豐富庫,包括:

  • 處理 html、字串、樣式、dom、正規表示式和若干其他實用工具的通用庫。
  • 包括字典、ArraryLists、佇列、SortedList、設定和堆疊的資料結構。
  • 用於新增動畫效果、驗證、拖放和若干其他功能的視覺化 Web 實用工具。
  • 數學和加密庫。
  • 儲存元件。
  • XML 解析

有關詳細資訊,請參見 http://manual.dojotoolkit.org/index.html

JSON 概述

JSON 是 JavaScript. 的物件文字元號的子集,它是在 JavaScript. 中表示資料結構的常用方法。JSON 是一種完全與語言無關的文字格式,但使用程式設計人員熟悉的與 C 語言家族(包括 C、C++、C#、Java、JavaScript、Perl、Python 和許多其他語言)類似的約定。這些屬性使 JSON 成為 Ajax 客戶端的理想資料交換語言。

JSON 構建在兩種結構的基礎上:

  1. 名稱/值對的集合。在不同的語言中,它被實現為物件、記錄、結構、字典、雜湊表、有鍵列表或者關聯陣列。
  2. 值的有序列表。在大多數語言中,它被實現為陣列、向量、列表或序列。

JSON 物件的示例如下:

var myJSONObject = {"id": 4, "name": "Roland Barcia", "pets": ["dog","cat","fish"]};
	

在示例中,我們對值對進行了命名。括號中的任何內容都是一個列表。在不同的程式語言中都有一組豐富的實現。有關詳細資訊,請參見 http://json.org/

JSON-RPC

JSON-RPC 是一種輕量級遠端過程呼叫協議,在此協議中,JSON 可以連續請求和響應。向遠端服務傳送請求可以呼叫遠端方法。該請求是具有三個屬性的單個物件:

  • method - 包含要呼叫的方法名稱的字串。
  • params - 作為引數傳遞到方法的物件陣列。
  • id - 請求 ID。它可以屬於任何型別。它用於將響應與其應答的請求相匹配。

當方法呼叫完成時,服務必須對響應進行應答。此響應是具有三個屬性的單個物件:

  • result - 被呼叫方法返回的物件。它必須為 null,以避免在呼叫該方法時發生錯誤。
  • error - error 物件(如果在呼叫方法時發生錯誤)。它必須為 null(如果不存在任何錯誤)。
  • id - 它必須是與響應的請求相同的 ID。

通知是沒有響應的特殊請求。它與帶有一個異常的請求物件具有相同的屬性:

  • id - 必須為 null

JSON 與 XML

XML 是一種用於面向服務的體系結構 (SOA) 和資料傳輸的常見傳輸。當然,目前許多服務以 SOAP 格式存在。不過,何時將其用於資料傳輸在 Ajax 社群中存在分岐。JSON 有以下幾個優點:

  • 瀏覽器解析 JSON 的速度比 XML 快。
  • JSON 構造是友好的程式語言,並容易轉換為後端程式語言(如 Java)。
  • JSON 相當穩定。JSON 的附加內容將成為超集。

XML 有以下優點:

  • 呼叫將 XML 用作傳輸的現有服務。
  • 使用 XSLT 可以動態轉換 XML。這是企業服務匯流排 (ESB) 方案中的理想功能。

用於 Dojo 的 JSON-RPC

Dojo 為呼叫 JSON-RPC 請求提供了抽象層。用於 Dojo 的 JSON-RPC 引入了標準方法描述(Standard Method Description,SMD)的概念。SMD 檔案是 JSON-RPC 服務的描述。它允許您以中立方式描述 JSON 呼叫。清單 6 提供了此類 JSON 呼叫的示例:


清單 6. Dojo 中的 SON 呼叫
{"SMDVersion":".1",
 "objectName":"StockService",
 "serviceType":"JSON-RPC",
 "serviceURL":"/DojoJ2EE/JSON-RPC",
 "methods":[
		{"name":"getStockData",
		"parameters":[
			{"name":"symbol",
			"type":"STRING"}
		 ]
    }
  ]
 }
	

您可以使用 Dojo API 呼叫服務:

var StockService = new dojo.rpc.JsonService("/path/to/StockService.smd"); StockService.getStockData("IBM",stockResultCallback);

這將通過網路傳送此結構:

{"id": 2, "method": "getStockData", "params": ["IBM"]}

JSON-RPC Java ORB

JSON-RPC 為遠端過程呼叫定義標準格式,但是不存在對後端技術的標準對映。JSON-RPC Java Orb 提供了這樣一種機制:註冊 Java 物件,並將它們公開為 JSON-PRC 服務。它還在 JavaScript. 中提供客戶端 API,以呼叫服務。

如果您選擇使用 Dojo,則可以編寫自已的繫結程式碼。用於 Java 的 JSON API 可以提供幫助。有關詳細資訊,請參見 (http://developer.berlios.de/projects/jsontools/)。在我們的示例中,我們將使用 JSON-RPC Java ORB 進行非同步請求,以利用伺服器端繫結程式碼。

JSON-RPC Java Orb 允許您在一種 Servlet 範圍(請求、會話、應用程式)內註冊 Java 物件。然後,它可以使用 JSON-RPC 請求來呼叫 Java 物件。為此,可以將物件型別放在 JSON 物件之前。由於 Dojo API 不執行此操作,所以用於 JSON-RPC 的 Dojo 客戶端 API 與用於 Java 的 JSON-RPC 不相容。

清單 7 提供瞭如何向 HttpSession 註冊 Java 物件的示例:


清單 7. 註冊 Java 物件的 HttpSession
HttpSession session = sessionEvent.getSession();
JSONRPCBridge json_bridge = null;
json_bridge = (JSONRPCBridge) session.getAttribute("JSONRPCBridge");
if(json_bridge == null) {
		json_bridge = new JSONRPCBridge();
		session.setAttribute("JSONRPCBridge", json_bridge);
}
json_bridge.registerObject
("StockService",StockServiceImpl.getStockService());
			

您可以在 Servlet 或 HttpListener 中執行此操作。然後將 JavaScript. 客戶端寫入到 Java 服務,如清單 8 所示。


清單 8. 連線 Java 服務的 JSONRpcClient
jsonrpc = new JSONRpcClient("/DojoJ2EE/JSON-RPC");
var stockButton = dojo.byId('stockInput');
jsonrpc.StockService.getStockData(stockResultCallBack,stockButton.value);
	

此請求會傳送以下有效負載:

{"id": 2, "method": "StockService.getStockData", "params": ["IBM"]}

響應與以下所示類似:

{"result":{"javaClass":"com.ibm.issw.json.service.StockData","price":100, "companyName":"International Business Machine","symbol":"IBM"},"id":2}

用於 Java 客戶端的 JSON-RPC 將處理此響應,並向您提供一個靜態介面。

為了支援請求,您需要註冊特殊的 Servlet。稍後,我將向您介紹如何執行此操作。

JSON-RPC Java ORB 的一個缺點是隻有單個 URL,這導致使用 Java EE 安全來保護 URL 非常困難。作為一種變通方法,您可以在 HTTP 會話層註冊服務,並根據安全需要新增它們。





回頁首


為企業應用程式構建企業客戶端

在此部分中,我將討論一些設計原則,然後詳細講解一個示例。您可以下載完整的 WAR 檔案,並親自嘗試該應用程式。

模型-檢視-控制器

在 Java EE 領域中,模型-檢視-控制器 (MVC) 已經變得非常成熟,這歸功於 Struts 和 JavaServer Faces 之類的框架。使用 Ajax 可以進行正確的 MVC 設計,這對成功的 Web 應用程式至關重要。此外,SOA 允許直接從 Ajax 應用程式呼叫服務。這樣做有幾個優點,如 WebSphere 期刊文章 "AJAX Requests – Data or Markup?" 中所述。

圖 2 提供了 Ajax 客戶端和 Java EE 應用程式之間理想生態系統的簡要概述。


圖 2. Ajax 客戶端和 Java EE 應用程式之間的理想生態系統
Ajax 客戶端和 Java EE 應用程式之間的理想生態系統。

在伺服器端,業務和門戶功能現在被公開為某一型別的服務介面。在服務的形式下,應遵循正確的伺服器端最佳實踐。伺服器應用程式應公開過程粒度服務。JavaServer Faces 之類的框架現在負責執行初始呈現;不過,對於客戶端 Ajax 工具包,這是可選的。

在瀏覽器上,分離關注的內容非常重要。圖 3 突出顯示了 Java 伺服器檔案結構:


圖 3. Java 伺服器檔案結構
Java 伺服器檔案結構。

您可以選擇每頁有一個 JavaScript. 控制器。不過,對於複雜的門戶頁,您可以將相關事件分組成小型的控制器集。

控制器檔案應:

  1. 向小部件載入網路請求處理程式,如圖 4 所示:

    圖 4. 將請求處理程式附加到小部件
    將請求處理程式附加到小部件。

  2. 實現請求處理程式。請求處理程式不應有太多的邏輯。它們應委派給服務 Facade,以便與後端互動。
  3. 實現回撥處理程式方法。回撥應將呈現委派給獨立 JS 檔案。此外,它們應將儲存中間狀態的工作委派給獨立 Java 伺服器檔案。對於無狀態互動,可以直接將結果傳遞到 rendering.js 檔案。

圖 5 說明了元件之間的流:


圖 5. 從客戶端到請求處理程式,再到回撥處理程式的資訊流
從客戶端到請求處理程式,再到回撥處理程式的資訊流。

呈現檔案包含呈現元件的邏輯或基於事件結果的使用者介面。

Business Facades 應包含代理伺服器請求的方法。DataCopy 應維護需要本地儲存在瀏覽器中的本地檢視物件。

為 Dojo 設定 Java EE 應用程式

對於 Dojo,您必須新增 JavaScript. 檔案作為 Web 應用程式的一部分。您可以將 dojo 資料夾複製到 Web 應用程式資料夾,如圖 6 所示:


圖 6. 新增使用 Dojo 所必需的 JavaScript. 檔案
新增使用 Dojo 所必需的 .. 檔案。

為 JSON-RPC Java Orb 設定 Java EE 應用程式

為了在應用程式中使用 JSON-RPC Java Orb,您需要在 Web 應用程式的 lib 目錄中新增 json-rpc-1.0.jar。還需要將單個 jsonrpc.js 檔案新增到 Web 內容資料夾中,如圖 7 所示:


圖 7. 新增使用 JSON-RPC Java Orb 所必需的 JavaScript. 檔案
新增使用 JSON-RPC Java Orb 所必需的 .. 檔案。

為了使 Java EE 應用程式能夠接收用於 Java 請求的 JSON-RPC,您必須新增 JSONRPCServlet,如清單 9 所示:


清單 9. 使用 JSONRPCServlet 所需的程式碼

	
		com.metaparadigm.jsonrpc.JSONRPCServlet
	
	
		com.metaparadigm.jsonrpc.JSONRPCServlet
	



	
		com.metaparadigm.jsonrpc.JSONRPCServlet
	
	/JSON-RPC

	

對於 SOA

Ajax 使 SOA 客戶端更完美。在我們的示例中,我們使用了一個簡單的 Java 服務。

Java 服務

圖 8 是基於 Java 的服務模型:


圖 8. 基於 Java 的服務模型
基於 Java 的服務模型。

我們使用了一個簡單的硬編碼實現,如清單 10 所示:


清單 10. 簡單的硬編碼 Java 服務
public StockData getStockData(String symbol) throws StockException {
	if(symbol.equals("IBM"))
	{
		StockData stockData = new StockData();
		stockData.setCompanyName("International Business Machine");
		stockData.setSymbol(symbol);
		stockData.setPrice(100.00);
		return stockData;
	}
	else
	{
		throw new StockException("Symbol: " + symbol + " not found!");
	}	
}
	

使用 JSON-RPC 公開 Java 服務

為了公開 Java 應用程式,我使用了被稱為 ExportServices 的 HttpSessionListener,以便為使用者註冊服務,如清單 11 所示:


清單 11. ExportServices,即公開 Java 服務的 HttpSessionListener
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
	
import com.ibm.issw.json.service.StockServiceImpl;
import com.metaparadigm.jsonrpc.JSONRPCBridge;
	
public class ExportServices implements HttpSessionListener {
	
	public void sessionCreated(HttpSessionEvent sessionEvent) {
			
		HttpSession session = sessionEvent.getSession();
		JSONRPCBridge json_bridge = null;
		json_bridge = (JSONRPCBridge) session.getAttribute("JSONRPCBridge");
			if(json_bridge == null) {
				json_bridge = new JSONRPCBridge();
				session.setAttribute("JSONRPCBridge", json_bridge);
			}
		json_bridge.registerObject
			("StockService",StockServiceImpl.getStockService());
	}
	
	public void sessionDestroyed(HttpSessionEvent arg0) {
			
	}
	
}
	

您需要將偵聽器新增到應用程式中(通過將其新增到 web.xml),如清單 12 所示:


清單 12. 新增到 web.xml 的 ExportServices 偵聽器

	ExportServices

	

客戶端開發過程

設定了基礎結構並公開了服務之後,現在我們可以構建 Web 客戶端了。通過 Dojo,我們利用小部件構建網頁並利用事件模型。圖 9 說明了建議的開發過程:


圖 9. 開發過程示例
開發過程示例。

我將使用此過程演示該示例。

從小部件構建 UI

首先構建 UI。請參見清單 13,瞭解示例 UI。

建立 UI:

  1. 載入指令碼:
    1. dojo
    2. jsonrpc
    3. StockClientController
    4. resultRenderer
  2. 構建頁面,並結合使用 div 和 HTML 標記以建立 Dojo 小部件。

    清單 13. HTML UI
    
    Stock Form
    
    
    
    
    
    
    
    
    
    

    Stock Service

    Enter symbol:


  3. StockClientController.js 非常關鍵。在指令碼的開頭,使用 dojo.require 方法載入所需的小部件,然後初始化 Dojo 環境,如清單 14 所示。

    清單 14. 初始化 Dojo 環境的 StockClientController
    //require statements
    dojo.require("dojo.widget.*" );
    dojo.require("dojo.event.*");
    dojo.require("dojo.widget.Button2");
    dojo.require("dojo.widget.FloatingPane" );
    	
    //all dojo.require above this line
    dojo.hostenv.writeIncludes(); 
    dojo.require();	
    	

操作前後需要考慮的事項

在 Ajax 中,需要考慮的一件事是,在觸發事件之前,不要顯示某些使用者介面。不過,一種做法是放置 div 標記作為佔位符。然後,可以使用 DOM 或 Dojo API 訪問此區域,並新增動態 UI 元素。在我們的應用程式中,我新增了一個簡單的 div,以獲得以下結果:

附加樣式表

接下來,使用 CSS 新增樣式。CSS 是設定 Ajax 應用程式格式的標準方法。使用 CSS,您可以將樣式定義應用於多個 div 標記,方法是將標記的 class 屬性設定為該樣式的名稱。這允許您重用樣式定義。清單 15 顯示了我使用的樣式表:


清單 15. 在 UI 中使用的樣式表
@CHARSET "ISO-8859-1";

.layout
{
	width: 100%;
	height: 80%;
}
	
.stockContent
{
	width: 100%; 
	height: 90%;
	background-color: #F0F0F0 ; 
	padding: 10px;
}
	
.stockPane
{
	width: 40%; 
	height: 250px;
}
	
.exceptionMsg
{
	color: #FF0000;
}
	

服務檢視

接下來,一個好的想法是確保 UI 開發人員在 JavaScript. 中擁有一個服務檢視。Dojo 使用 SMD 來做到這一點,如前面所述。用於 Java 的 JSON-RPC 為我們提供了直接從 JavaScript. 呼叫 Java 服務的能力,如清單 16 所示:


清單 16. 直接呼叫 Java 服務的 JavaScript

jsonrpc.StockService.getStockData(stockResultCallBack,stockButton.value);
	

構建請求事件處理程式

接著,在控制器 JS 檔案中,我們需要建立事件處理程式和回撥處理程式。回撥處理程式應是其他工作的 Facade。在我們的示例中,事件處理程式將非同步呼叫我們的服務,並將回撥傳遞到相應的方法。XMLHttpRequest 物件的此抽象由 JSON-RPC-Java 提供。在接收到響應時,回撥委派給呈現,如清單 17 所示:


清單 17. 控制器檔案中的回撥和事件處理程式
function stockResultCallBack(result,exception) {
	try {
		renderStockResult(result,exception);
	} catch(e) {
		alert(e);
    } 	    
}

function submitStock()
	{
   	try {
		jsonrpc = new JSONRpcClient("/DojoJ2EE/JSON-RPC");
		var stockButton = dojo.byId('stockInput');
		jsonrpc.StockService.
			getStockData(stockResultCallBack,stockButton.value);
	} 
	catch(e) {
		alert(e);
	}
}
	

在載入時載入初始 UI 和網路請求事件

下面,我們在頁面初始化時使用 Dojo 這種有力的工具,將小部件連線到請求處理程式。請參見清單 18 中的 init 方法。dojo.addOnLoad() 方法允許您使用同一面向方面的技術,將 init 方法附加到頁面載入事件。


清單 18. init() 方法
function init()
	{
	var stockButton = dojo.widget.byId('stockButton');
	dojo.event.connect(stockButton, 'onClick', 'submitStock');
	}
dojo.addOnLoad(init);
	

呈現響應

最後一步是新增動態呈現響應程式碼。我將它放置在獨立呈現器 JS 檔案中。您可以使用各種方法來呈現響應。在我們的示例中,我們將結合使用 DOM API 和 Dojo 實用工具來構建簡單的表。在這裡,我們可以使用 Dojo 的小部件之一,但是我希望對清單 19 中的函式 renderStockResult 使用自已的程式碼,以便突出顯示一些 Dojo 實用工具和資料結構。

要建立呈現響應程式碼,請執行下列操作:

  1. renderStockResult 函式中,使用 dojo.byId() 方法訪問 resultArea 物件。
  2. 檢查任何異常;如果 renderStockResult 含有傳遞給它的異常,它會將該異常傳遞到錯誤處理程式並返回。
  3. 使用 Dictionary(類似於 Java HashMap)和 ArrayList Dojo 結構來存放 result 資料。
  4. 將結構化資料傳遞到通用表建立者方法。

清單 19. 呈現響應方法
dojo.require("dojo.collections.*");
dojo.require("dojo.fx.*");

function renderStockResult(result,exception)
{
	var resultArea = dojo.byId('resultArea');
	if(exception)
	{
		handleStockError(resultArea,exception);
		return;
	}
	
	var symbolHeader = "Symbol:";
	var priceHeader = "Price:";
	var companyNameHeader = "Company Name:";
	
	var headers = new dojo.collections.ArrayList();
	headers.add(symbolHeader);
	headers.add(priceHeader);
	headers.add(companyNameHeader);
	
	var column = new dojo.collections.Dictionary();
	
	column.add(symbolHeader,result.symbol);
	column.add(priceHeader,result.price);
	column.add(companyNameHeader,result.companyName);
	
	var data = new dojo.collections.ArrayList();
	
	data.add(column);
	
	createTableWithVerticleHeading(resultArea,headers,data);
		
}
	

設定了資料結構之後,呼叫具體的 createTableWithVerticleHeading 方法。實際上,此類實用工具將會被外部化。在下面顯示的方法中,我們將使用 Dojo Iterator 物件來遍歷這些資料結構並建立表。我要在下面指出的另一個方法是 dojo.fx.html.fadeShow(table, 200),您可以使用該方法將淡入效果新增到結果的列印中。這只是某些動畫的一瞬。在清單 20 中,Dojo 程式碼為粗體。


清單 20. 表建立方法
function createTableWithVerticleHeading(root,headers,data)
{
	
	var ldResult = dojo.byId('resultTable');
	if(oldResult)
	{
		root.removeChild(oldResult);
	}
	var exceptionMsg = dojo.byId('stockExceptionMsg');
	if(exceptionMsg)
	{
		resultArea.removeChild(exceptionMsg);
	}
	var table = document.createElement("table");
	dojo.fx.html.fadeShow(table, 200);
	table.setAttribute("id","resultTable");
	
	root.appendChild(table);
	var headerIter = headers.getIterator();
	
	
	while(!headerIter.atEnd())
	{
		var row = document.createElement("tr");
		table.appendChild(row);
		var element = document.createElement("th");
		element.setAttribute("align","left");
		row.appendChild(element);
		var header = headerIter.get();
		var dataElement = document.createTextNode(header);
		element.appendChild(dataElement);
		var dataIter = data.getIterator();
		while(!dataIter.atEnd())
		{
			var resultItem = dataIter.get();
			var item = resultItem.item(header);
			var elementItem = document.createElement("td");
			elementItem.setAttribute("align","left");
			row.appendChild(elementItem);
			var dataText = document.createTextNode(item);
			elementItem.appendChild(dataText);
		} 	
	}
}
	

最後,我們將新增簡單的錯誤處理方法,以列印錯誤訊息,如清單 21 所示。請記住,通過在元素上設定類屬性,然後委派給 CSS 檔案,可新增粗體文字。


清單 21. 錯誤處理方法
function handleStockError(resultArea,exception)
{
	var ldResult = dojo.byId('resultTable');
	if(oldResult)
	{
		resultArea.removeChild(oldResult);
	}
	var exceptionMsg = dojo.byId('stockExceptionMsg');
	if(exceptionMsg)
	{
		resultArea.removeChild(exceptionMsg);
	}
	var error = document.createElement("h4");
	error.setAttribute("class","exceptionMsg");
	error.setAttribute("id","stockExceptionMsg");
	var errorText = document.createTextNode(exception.message);
	resultArea.appendChild(error);
	error.appendChild(errorText);
	
	return;
}

測試應用程式

您可以下載應用程式的最終 WAR 檔案。可將其安裝在任何應用伺服器(如 WebSphere Application Server)上。部署了應用程式後,您可以開啟 HTML 頁,以檢視浮點形式,如圖 10 所示:


圖 10. HTML 中的浮點形式
HTML 中的浮點形式

可以自由移動該形式。您可能注意到,我已將浮點繫結到外部容器,如圖 11 所示:


圖 11. 繫結到外部容器的浮點
繫結到外部容器的浮點。

輸入 IBM 以呼叫 Java EE 應用程式。結果應類似於圖 12 所示的形式:


圖 12. 將 IBM 輸入到應用程式的結果
將 IBM 輸入到應用程式的結果。

接下來,輸入一些其他資料,以測試錯誤處理程式,如圖 13 所示。


圖 13. 測試錯誤處理程式
測試錯誤處理程式。

Dojo 還提供了單元測試套件以自動執行單元測試。

結束語

在本文中,我向您介紹瞭如何使用 Dojo 工具包、JSON 和 JSON-RPC 為 Java EE 應用程式構建 Ajax 客戶端。我概述了每項技術,並介紹了一些設計原則。最後,我提供了一個示例應用程式。Ajax 應用程式將很快成為 SOA 客戶端。通過使用 Dojo 之類的工具包,您可以方便地構建這些網頁。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14789789/viewspace-434482/,如需轉載,請註明出處,否則將追究法律責任。

相關文章