小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 pengyan 2006-11-20
developerWorks


1


級別: 中級

Roland Barcia (barcia@us.ibm.com), IT 咨詢專家, IBM WebSphere 軟件服務部

2006 年 8 月 21 日

了 解如何使用 Dojo 工具包為 Java? Platform Extended Edition (Java EE) 應用程序構建企業(yè) SOA 客戶端,以及如何使用 JavaScript Object Notation–RPC (JSON-RPC) 來調用服務器端 Java 對象。

引言

異 步 JavaScript 和 XML (Ajax) 是使用本機瀏覽器技術構建富 Web 應用程序的新方法。對于編寫需要某些類型的“活動”用戶界面的復雜應用程序的開發(fā)人員,JavaScript 在這方面已經(jīng)做得很好。不過,JavaScript 難于編碼、調試、移植和維護。使用 Ajax 工具包有助于最大程度地減少使用 JavaScript 和 Ajax 帶來的許多常見問題。優(yōu)秀的 Ajax 工具包提供了一組可重用的小部件、用于擴展和創(chuàng)建小部件的框架、事件系統(tǒng)、JavaScript 實用工具和增強的異步服務器調用支持。在本文中,我們將討論如何使用 Dojo 工具包為 Java EE 應用程序構建企業(yè) SOA 客戶端。我們還將使用 JSON (JavaScript Object Notation)–RPC 來調用服務器端 Java 對象。

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





回頁首


Ajax 概述

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

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

  • JavaScript,它可以編排頁面元素,從而獲得最佳 Ajax 用戶體驗。
  • Cascading Style Sheets (CSS),它可以定義頁面元素的可視樣式。
  • 文檔對象模型(Document Object Model,DOM),它將網(wǎng)頁結構作為一組可以使用 JavaScript 操作的可編程對象提供。
  • XMLHttpRequest,它支持以后臺活動的形式從 Web 資源檢索數(shù)據(jù)。

XMLHttpRequest 對象是關鍵部分。

XMLHttpRequest 對象

XMLHttpRequest 對象是 Ajax 用于進行異步請求的機制。圖 1 說明了該流程:


圖 1. XMLHttpRequest 對象進行異步請求的流程圖
XMLHttpRequest 對象進行異步請求的流程圖。

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

  1. 頁面調用某個 JavaScript。
  2. JavaScript 函數(shù)創(chuàng)建 XMLHttpRequest 對象。這包括設置要調用的 URL 和 HTTP 請求參數(shù)。
  3. JavaScript 函數(shù)注冊回調處理程序。HTTP 響應調用此回調處理程序。
  4. JavaScript 函數(shù)調用 XMLHttpRequest 對象上的 send 方法,該方法接著將 HTTP 請求發(fā)送到服務器。
  5. XMLHttpRequest 對象立即將控制返回到 JavaScript 方法。此時,用戶可以繼續(xù)使用該頁面。
  6. 稍后,HTTP 服務器通過調用回調處理程序返回 HTTP 響應。
  7. 回調處理程序可以訪問 HTML DOM 對象。它可以動態(tài)更新頁面元素,而無需中斷用戶(除非您碰巧更新用戶正在使用的 DOM 對象)。

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





回頁首


Dojo 工具包概述

Dojo 使您能夠方便地構建動態(tài)站點。它提供一個豐富的小部件庫,您可以使用它組成頁面。您可以使用基于 Dojo 方面的事件系統(tǒng)將事件附加到組件,以創(chuàng)建豐富的交互體驗。此外,您可以使用幾個 Dojo 庫進行異步服務器請求、添加動畫效果和瀏覽存儲實用工具等等。

Dojo 小部件

Dojo 提供了您可以用于構建頁面的一組豐富的小部件。您可以使用多個方法創(chuàng)建 Dojo 小部件。Dojo 的眾多優(yōu)點之一是它允許您使用標準的 HTML 標記。然后,可以將這些標記用于小部件。這樣,HTML 開發(fā)人員就可以方便地使用 Dojo,如清單 1 所示:


清單 1. 在 HTML 標記中使用 Dojo
<div dojoType="FloatingPane" class="stockPane" title="Stock Form" id="pane"
                    constrainToContainer="true" displayMaximizeAction="true">
                    <h2>Stock Service</h2>
                    Enter symbol: <input dojoType="ValidationTextBox" required="true"
                    id="stockInput">
                    <p />
                    <button dojoType="Button2" widgetId="stockButton">
                    Get Stock Data
                    </button>
                    <div id="resultArea" />
                    </div>
                    

您可以使用 div 標記來定義小部件的位置,而在頁面加載或對事件進行響應時 Dojo 可以在這些地方放置小部件。您還可以使用更具體的標記,如 <dojo:widget>,并向其中添加 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 中創(chuàng)建、訪問、修改和刪除小部件,從而實現(xiàn)動態(tài)行為。在我們的示例中,您將看到在 JavaScript 中訪問小部件的示例。

Dojo 事件系統(tǒng)

Dojo 事件系統(tǒng)使用面向方面的技術將事件附加到小部件。這可以將小部件與實際的事件處理分離。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 節(jié)點上附加 dojoAttachEvent,如下所示。某些 HTML 標記沒有定義事件,所以這是一個方便的擴展。


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

Dojo 事件系統(tǒng)還允許多個高級功能,如:

  • 聲明在現(xiàn)有的事件處理程序之前或之后插入事件處理程序的建議。
  • 允許小部件在瀏覽器中訂閱或發(fā)布主題。
  • 添加事件回調。
  • 可用于表示事件的 event 規(guī)范化對象。

有關詳細信息,請參見 http://dojo./EventExamples。

Dojo 異步服務器請求

Dojo 通過抽象特定于瀏覽器的詳細信息,提供了對服務器進行異步請求的簡單方法。Dojo 允許您創(chuàng)建數(shù)據(jù)結構來隱藏詳細信息,如清單 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、設置和堆棧的數(shù)據(jù)結構。
  • 用于添加動畫效果、驗證、拖放和若干其他功能的可視化 Web 實用工具。
  • 數(shù)學和加密庫。
  • 存儲組件。
  • XML 解析

有關詳細信息,請參見 http://manual./index.html





回頁首


JSON 概述

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

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

  1. 名稱/值對的集合。在不同的語言中,它被實現(xiàn)為對象、記錄、結構、字典、哈希表、有鍵列表或者關聯(lián)數(shù)組。
  2. 值的有序列表。在大多數(shù)語言中,它被實現(xiàn)為數(shù)組、向量、列表或序列。

JSON 對象的示例如下:

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

在示例中,我們對值對進行了命名。括號中的任何內容都是一個列表。在不同的編程語言中都有一組豐富的實現(xiàn)。有關詳細信息,請參見 http:///

JSON-RPC

JSON-RPC 是一種輕量級遠程過程調用協(xié)議,在此協(xié)議中,JSON 可以連續(xù)請求和響應。向遠程服務發(fā)送請求可以調用遠程方法。該請求是具有三個屬性的單個對象:

  • method - 包含要調用的方法名稱的字符串。
  • params - 作為參數(shù)傳遞到方法的對象數(shù)組。
  • id - 請求 ID。它可以屬于任何類型。它用于將響應與其應答的請求相匹配。

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

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

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

  • id - 必須為 null

JSON 與 XML

XML 是一種用于面向服務的體系結構 (SOA) 和數(shù)據(jù)傳輸?shù)某R妭鬏?。當然,目前許多服務以 SOAP 格式存在。不過,何時將其用于數(shù)據(jù)傳輸在 Ajax 社區(qū)中存在分岐。JSON 有以下幾個優(yōu)點:

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

XML 有以下優(yōu)點:

  • 調用將 XML 用作傳輸?shù)默F(xiàn)有服務。
  • 使用 XSLT 可以動態(tài)轉換 XML。這是企業(yè)服務總線 (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);

這將通過網(wǎng)絡發(fā)送此結構:

{"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./projects/jsontools/)。在我們的示例中,我們將使用 JSON-RPC Java ORB 進行異步請求,以利用服務器端綁定代碼。

JSON-RPC Java Orb 允許您在一種 Servlet 范圍(請求、會話、應用程序)內注冊 Java 對象。然后,它可以使用 JSON-RPC 請求來調用 Java 對象。為此,可以將對象類型放在 JSON 對象之前。由于 Dojo API 不執(zhí)行此操作,所以用于 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 中執(zhí)行此操作。然后將 JavaScript 客戶端寫入到 Java 服務,如清單 8 所示。


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

此請求會發(fā)送以下有效負載:

{"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 將處理此響應,并向您提供一個靜態(tài)接口。

為了支持請求,您需要注冊特殊的 Servlet。稍后,我將向您介紹如何執(zhí)行此操作。

JSON-RPC Java ORB 的一個缺點是只有單個 URL,這導致使用 Java EE 安全來保護 URL 非常困難。作為一種變通方法,您可以在 HTTP 會話層注冊服務,并根據(jù)安全需要添加它們。





回頁首


為企業(yè)應用程序構建企業(yè)客戶端

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

模型-視圖-控制器

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

圖 2 提供了 Ajax 客戶端和 Java EE 應用程序之間理想生態(tài)系統(tǒng)的簡要概述。


圖 2. Ajax 客戶端和 Java EE 應用程序之間的理想生態(tài)系統(tǒng)
Ajax 客戶端和 java ee 應用程序之間的理想生態(tài)系統(tǒng)。

在服務器端,業(yè)務和門戶功能現(xiàn)在被公開為某一類型的服務接口。在服務的形式下,應遵循正確的服務器端最佳實踐。服務器應用程序應公開過程粒度服務。JavaServer Faces 之類的框架現(xiàn)在負責執(zhí)行初始呈現(xiàn);不過,對于客戶端 Ajax 工具包,這是可選的。

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


圖 3. Java 服務器文件結構
Java 服務器文件結構。

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

控制器文件應:

  1. 向小部件加載網(wǎng)絡請求處理程序,如圖 4 所示:

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

  2. 實現(xiàn)請求處理程序。請求處理程序不應有太多的邏輯。它們應委派給服務 Facade,以便與后端交互。
  3. 實現(xiàn)回調處理程序方法。回調應將呈現(xiàn)委派給獨立 JS 文件。此外,它們應將存儲中間狀態(tài)的工作委派給獨立 Java 服務器文件。對于無狀態(tài)交互,可以直接將結果傳遞到 rendering.js 文件。

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


圖 5. 從客戶端到請求處理程序,再到回調處理程序的信息流
從客戶端到請求處理程序,再到回調處理程序的信息流。

呈現(xiàn)文件包含呈現(xiàn)組件的邏輯或基于事件結果的用戶界面。

Business Facades 應包含代理服務器請求的方法。DataCopy 應維護需要本地保存在瀏覽器中的本地視圖對象。

為 Dojo 設置 Java EE 應用程序

對于 Dojo,您必須添加 JavaScript 文件作為 Web 應用程序的一部分。您可以將 dojo 文件夾復制到 Web 應用程序文件夾,如圖 6 所示:


圖 6. 添加使用 Dojo 所必需的 JavaScript 文件
添加使用 dojo 所必需的 javascript 文件。

為 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 所必需的 javascript 文件。

為了使 Java EE 應用程序能夠接收用于 Java 請求的 JSON-RPC,您必須添加 JSONRPCServlet,如清單 9 所示:


清單 9. 使用 JSONRPCServlet 所需的代碼
<servlet>
                    <servlet-name>
                    com.metaparadigm.jsonrpc.JSONRPCServlet
                    </servlet-name>
                    <servlet-class>
                    com.metaparadigm.jsonrpc.JSONRPCServlet
                    </servlet-class>
                    </servlet>
                    <servlet-mapping>
                    <servlet-name>
                    com.metaparadigm.jsonrpc.JSONRPCServlet
                    </servlet-name>
                    <url-pattern>/JSON-RPC</url-pattern>
                    </servlet-mapping>
                    

對于 SOA

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

Java 服務

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


圖 8. 基于 Java 的服務模型
基于 java 的服務模型。

我們使用了一個簡單的硬編碼實現(xiàn),如清單 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 偵聽器
<listener>
                    <listener-class>ExportServices</listener-class>
                    </listener>
                    

客戶端開發(fā)過程

設置了基礎結構并公開了服務之后,現(xiàn)在我們可以構建 Web 客戶端了。通過 Dojo,我們利用小部件構建網(wǎng)頁并利用事件模型。圖 9 說明了建議的開發(fā)過程:


圖 9. 開發(fā)過程示例
開發(fā)過程示例。

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

從小部件構建 UI

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

創(chuàng)建 UI:

  1. 加載腳本:
    1. dojo
    2. jsonrpc
    3. StockClientController
    4. resultRenderer
  2. 構建頁面,并結合使用 div 和 HTML 標記以創(chuàng)建 Dojo 小部件。

    清單 13. HTML UI
    <html>
                            <head>
                            <title>Stock Form</title>
                            <script type="text/javascript" src="../dojoAjax/dojo.js"></script>
                            <script type="text/javascript" src="../jsonrpc.js"></script>
                            <script type="text/javascript" src="../view/resultRender.js"></script>
                            <script type="text/javascript"
                            src="../controller/StockClientController.js"></script>
                            <link REL=StyleSheet HREF="../StockApp.css" TYPE="text/css" ></link>
                            </head>
                            <body>
                            <div class="layout" dojoType="LayoutContainer">
                            <div dojoType="ContentPane" class="stockContent" layoutAlign="bottom"
                            id="docpane" isContainer="true" executeScripts="true">
                            <div dojoType="FloatingPane" class="stockPane" title="Stock Form"
                            id="pane" constrainToContainer="true" displayMaximizeAction="true">
                            <h2>Stock Service</h2>
                            Enter symbol: <input dojoType="ValidationTextBox" required="true"
                            id="stockInput">
                            <p />
                            <button dojoType="Button2" widgetId="stockButton">
                            Get Stock Data
                            </button>
                            <div id="resultArea" />
                            </div>
                            </div>
                            </div>
                            </body>
                            </html>
                            

  3. StockClientController.js 非常關鍵。在腳本的開頭,使用 dojo.require 方法加載所需的小部件,然后初始化 Dojo 環(huán)境,如清單 14 所示。

    清單 14. 初始化 Dojo 環(huán)境的 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 中,需要考慮的一件事是,在觸發(fā)事件之前,不要顯示某些用戶界面。不過,一種做法是放置 div 標記作為占位符。然后,可以使用 DOM 或 Dojo API 訪問此區(qū)域,并添加動態(tài) UI 元素。在我們的應用程序中,我添加了一個簡單的 div,以獲得以下結果:

<div id="resultArea" />

附加樣式表

接下來,使用 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 開發(fā)人員在 JavaScript 中擁有一個服務視圖。Dojo 使用 SMD 來做到這一點,如前面所述。用于 Java 的 JSON-RPC 為我們提供了直接從 JavaScript 調用 Java 服務的能力,如清單 16 所示:


清單 16. 直接調用 Java 服務的 JavaScript
<script type="text/javascript" src="../jsonrpc.js"></script>
                    jsonrpc.StockService.getStockData(stockResultCallBack,stockButton.value);
                    

構建請求事件處理程序

接著,在控制器 JS 文件中,我們需要創(chuàng)建事件處理程序和回調處理程序?;卣{處理程序應是其他工作的 Facade。在我們的示例中,事件處理程序將異步調用我們的服務,并將回調傳遞到相應的方法。XMLHttpRequest 對象的此抽象由 JSON-RPC-Java 提供。在接收到響應時,回調委派給呈現(xiàn),如清單 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 和網(wǎng)絡請求事件

下面,我們在頁面初始化時使用 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);
                    

呈現(xiàn)響應

最 后一步是添加動態(tài)呈現(xiàn)響應代碼。我將它放置在獨立呈現(xiàn)器 JS 文件中。您可以使用各種方法來呈現(xiàn)響應。在我們的示例中,我們將結合使用 DOM API 和 Dojo 實用工具來構建簡單的表。在這里,我們可以使用 Dojo 的小部件之一,但是我希望對清單 19 中的函數(shù) renderStockResult 使用自已的代碼,以便突出顯示一些 Dojo 實用工具和數(shù)據(jù)結構。

要創(chuàng)建呈現(xiàn)響應代碼,請執(zhí)行下列操作:

  1. renderStockResult 函數(shù)中,使用 dojo.byId() 方法訪問 resultArea 對象。
  2. 檢查任何異常;如果 renderStockResult 含有傳遞給它的異常,它會將該異常傳遞到錯誤處理程序并返回。
  3. 使用 Dictionary(類似于 Java HashMap)和 ArrayList Dojo 結構來存放 result 數(shù)據(jù)。
  4. 將結構化數(shù)據(jù)傳遞到通用表創(chuàng)建者方法。

清單 19. 呈現(xiàn)響應方法
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);
                    }
                    

設置了數(shù)據(jù)結構之后,調用具體的 createTableWithVerticleHeading 方法。實際上,此類實用工具將會被外部化。在下面顯示的方法中,我們將使用 Dojo Iterator 對象來遍歷這些數(shù)據(jù)結構并創(chuàng)建表。我要在下面指出的另一個方法是 dojo.fx.html.fadeShow(table, 200),您可以使用該方法將淡入效果添加到結果的打印中。這只是某些動畫的一瞬。在清單 20 中,Dojo 代碼為粗體。


清單 20. 表創(chuàng)建方法
function createTableWithVerticleHeading(root,headers,data)
                    {
                    var oldResult = 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 oldResult = 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 文件??蓪⑵浒惭b在任何應用服務器(如 WebSphere Application Server)上。部署了應用程序后,您可以打開 HTML 頁,以查看浮點形式,如圖 10 所示:


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

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


圖 11. 綁定到外部容器的浮點
綁定到外部容器的浮點。

輸入 IBM 以調用 Java EE 應用程序。結果應類似于圖 12 所示的形式:


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

接下來,輸入一些其他數(shù)據(jù),以測試錯誤處理程序,如圖 13 所示。


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

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





回頁首


結束語

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





回頁首


致謝

非常感謝 Chris Mitchell 審閱了這篇文章并提出了寶貴的意見。






回頁首


下載

描述名字大小下載方法
Sample code for this article DojoJ2EE.war 1.8MB  FTP|HTTP
關于下載方法的信息 Get Adobe? Reader?




回頁首


參考資料

學習

獲得產(chǎn)品和技術

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多