免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
使用 Dojo 工具包和 JSON-RPC 構(gòu)建企業(yè) SOA Ajax 客戶端


1


級別: 中級

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

2006 年 8 月 21 日

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

引言

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

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





回頁首


Ajax 概述

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

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

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

XMLHttpRequest 對象是關(guān)鍵部分。

XMLHttpRequest 對象

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


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

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

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

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





回頁首


Dojo 工具包概述

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

Dojo 小部件

Dojo 提供了您可以用于構(gòu)建頁面的一組豐富的小部件。您可以使用多個方法創(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 標記來定義小部件的位置,而在頁面加載或?qū)κ录M行響應(yīng)時 Dojo 可以在這些地方放置小部件。您還可以使用更具體的標記,如 <dojo:widget>,并向其中添加 Dojo 小部件屬性。在清單 1 中,我們將 dojoType 屬性添加到 button 標記。在設(shè)置了標記之后,您需要在一些 JavaScript 內(nèi)部加載小部件,如清單 2 所示。您可以將標記嵌入到頁面內(nèi)部,但是我們建議將其放置在單獨的 JS 文件中。在本文的稍后部分中,我們將闡明一些 MVC 設(shè)計原則。


清單 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)使用面向方面的技術(shù)將事件附加到小部件。這可以將小部件與實際的事件處理分離。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ā)布主題。
  • 添加事件回調(diào)。
  • 可用于表示事件的 event 規(guī)范化對象。

有關(guān)詳細信息,請參見 http://dojo.jot.com/EventExamples

Dojo 異步服務(wù)器請求

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

有關(guān)詳細信息,請參見 http://manual.dojotoolkit.org/index.html





回頁首


JSON 概述

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

JSON 構(gòu)建在兩種結(jié)構(gòu)的基礎(chǔ)上:

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

JSON 對象的示例如下:

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

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

JSON-RPC

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

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

當方法調(diào)用完成時,服務(wù)必須對響應(yīng)進行應(yīng)答。此響應(yīng)是具有三個屬性的單個對象:

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

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

  • id - 必須為 null

JSON 與 XML

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

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

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

  • 調(diào)用將 XML 用作傳輸?shù)默F(xiàn)有服務(wù)。
  • 使用 XSLT 可以動態(tài)轉(zhuǎn)換 XML。這是企業(yè)服務(wù)總線 (ESB) 方案中的理想功能。

用于 Dojo 的 JSON-RPC

Dojo 為調(diào)用 JSON-RPC 請求提供了抽象層。用于 Dojo 的 JSON-RPC 引入了標準方法描述(Standard Method Description,SMD)的概念。SMD 文件是 JSON-RPC 服務(wù)的描述。它允許您以中立方式描述 JSON 調(diào)用。清單 6 提供了此類 JSON 調(diào)用的示例:


清單 6. Dojo 中的 SON 調(diào)用
{"SMDVersion":".1",                    "objectName":"StockService",                    "serviceType":"JSON-RPC",                    "serviceURL":"/DojoJ2EE/JSON-RPC",                    "methods":[                    {"name":"getStockData",                    "parameters":[                    {"name":"symbol",                    "type":"STRING"}                    ]                    }                    ]                    }                    

您可以使用 Dojo API 調(diào)用服務(wù):

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

這將通過網(wǎng)絡(luò)發(fā)送此結(jié)構(gòu):

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

JSON-RPC Java ORB

JSON-RPC 為遠程過程調(diào)用定義標準格式,但是不存在對后端技術(shù)的標準映射。JSON-RPC Java Orb 提供了這樣一種機制:注冊 Java 對象,并將它們公開為 JSON-PRC 服務(wù)。它還在 JavaScript 中提供客戶端 API,以調(diào)用服務(wù)。

如果您選擇使用 Dojo,則可以編寫自已的綁定代碼。用于 Java 的 JSON API 可以提供幫助。有關(guān)詳細信息,請參見 (http://developer.berlios.de/projects/jsontools/)。在我們的示例中,我們將使用 JSON-RPC Java ORB 進行異步請求,以利用服務(wù)器端綁定代碼。

JSON-RPC Java Orb 允許您在一種 Servlet 范圍(請求、會話、應(yīng)用程序)內(nèi)注冊 Java 對象。然后,它可以使用 JSON-RPC 請求來調(diào)用 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 服務(wù),如清單 8 所示。


清單 8. 連接 Java 服務(wù)的 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"]}

響應(yīng)與以下所示類似:

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

用于 Java 客戶端的 JSON-RPC 將處理此響應(yīng),并向您提供一個靜態(tài)接口。

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

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





回頁首


為企業(yè)應(yīng)用程序構(gòu)建企業(yè)客戶端

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

模型-視圖-控制器

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

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


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

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

在瀏覽器上,分離關(guān)注的內(nèi)容非常重要。圖 3 突出顯示了 Java 服務(wù)器文件結(jié)構(gòu):


圖 3. Java 服務(wù)器文件結(jié)構(gòu)

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

控制器文件應(yīng):

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

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


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

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


圖 5. 從客戶端到請求處理程序,再到回調(diào)處理程序的信息流

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

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

為 Dojo 設(shè)置 Java EE 應(yīng)用程序

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


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

為 JSON-RPC Java Orb 設(shè)置 Java EE 應(yīng)用程序

為了在應(yīng)用程序中使用 JSON-RPC Java Orb,您需要在 Web 應(yīng)用程序的 lib 目錄中添加 json-rpc-1.0.jar。還需要將單個 jsonrpc.js 文件添加到 Web 內(nèi)容文件夾中,如圖 7 所示:


圖 7. 添加使用 JSON-RPC Java Orb 所必需的 JavaScript 文件

為了使 Java EE 應(yīng)用程序能夠接收用于 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 服務(wù)。

Java 服務(wù)

圖 8 是基于 Java 的服務(wù)模型:


圖 8. 基于 Java 的服務(wù)模型

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


清單 10. 簡單的硬編碼 Java 服務(wù)
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 服務(wù)

為了公開 Java 應(yīng)用程序,我使用了被稱為 ExportServices 的 HttpSessionListener,以便為用戶注冊服務(wù),如清單 11 所示:


清單 11. ExportServices,即公開 Java 服務(wù)的 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) {                    }                    }                    

您需要將偵聽器添加到應(yīng)用程序中(通過將其添加到 web.xml),如清單 12 所示:


清單 12. 添加到 web.xml 的 ExportServices 偵聽器
<listener>                    <listener-class>ExportServices</listener-class>                    </listener>                    

客戶端開發(fā)過程

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


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

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

從小部件構(gòu)建 UI

首先構(gòu)建 UI。請參見清單 13,了解示例 UI。

創(chuàng)建 UI:

  1. 加載腳本:
    1. dojo
    2. jsonrpc
    3. StockClientController
    4. resultRenderer
  2. 構(gòu)建頁面,并結(jié)合使用 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 非常關(guān)鍵。在腳本的開頭,使用 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 元素。在我們的應(yīng)用程序中,我添加了一個簡單的 div,以獲得以下結(jié)果:

<div id="resultArea" />

附加樣式表

接下來,使用 CSS 添加樣式。CSS 是設(shè)置 Ajax 應(yīng)用程序格式的標準方法。使用 CSS,您可以將樣式定義應(yīng)用于多個 div 標記,方法是將標記的 class 屬性設(shè)置為該樣式的名稱。這允許您重用樣式定義。清單 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;                    }                    

服務(wù)視圖

接 下來,一個好的想法是確保 UI 開發(fā)人員在 JavaScript 中擁有一個服務(wù)視圖。Dojo 使用 SMD 來做到這一點,如前面所述。用于 Java 的 JSON-RPC 為我們提供了直接從 JavaScript 調(diào)用 Java 服務(wù)的能力,如清單 16 所示:


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

構(gòu)建請求事件處理程序

接著,在控制器 JS 文件中,我們需要創(chuàng)建事件處理程序和回調(diào)處理程序?;卣{(diào)處理程序應(yīng)是其他工作的 Facade。在我們的示例中,事件處理程序?qū)惒秸{(diào)用我們的服務(wù),并將回調(diào)傳遞到相應(yīng)的方法。XMLHttpRequest 對象的此抽象由 JSON-RPC-Java 提供。在接收到響應(yīng)時,回調(diào)委派給呈現(xiàn),如清單 17 所示:


清單 17. 控制器文件中的回調(diào)和事件處理程序
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)絡(luò)請求事件

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


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

呈現(xiàn)響應(yīng)

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

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

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

清單 19. 呈現(xiàn)響應(yīng)方法
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è)置了數(shù)據(jù)結(jié)構(gòu)之后,調(diào)用具體的 createTableWithVerticleHeading 方法。實際上,此類實用工具將會被外部化。在下面顯示的方法中,我們將使用 Dojo Iterator 對象來遍歷這些數(shù)據(jù)結(jié)構(gòu)并創(chuàng)建表。我要在下面指出的另一個方法是 dojo.fx.html.fadeShow(table, 200),您可以使用該方法將淡入效果添加到結(jié)果的打印中。這只是某些動畫的一瞬。在清單 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 所示。請記住,通過在元素上設(shè)置類屬性,然后委派給 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;                    }                    

測試應(yīng)用程序

您可以下載應(yīng)用程序的最終 WAR 文件??蓪⑵浒惭b在任何應(yīng)用服務(wù)器(如 WebSphere Application Server)上。部署了應(yīng)用程序后,您可以打開 HTML 頁,以查看浮點形式,如圖 10 所示:


圖 10. HTML 中的浮點形式

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


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

輸入 IBM 以調(diào)用 Java EE 應(yīng)用程序。結(jié)果應(yīng)類似于圖 12 所示的形式:


圖 12. 將 IBM 輸入到應(yīng)用程序的結(jié)果

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


圖 13. 測試錯誤處理程序

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





回頁首


結(jié)束語

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





回頁首


致謝

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






回頁首


下載

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




回頁首


參考資料

學(xué)習(xí)

獲得產(chǎn)品和技術(shù)
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
面向 Java 開發(fā)人員的 Ajax(二): Ajax 的 Java 對象序列化
使用 Dojo 的 Ajax 應(yīng)用開發(fā)進階教程,第 6 部分: Dojo 基本庫深入介紹
使用 Dojo 和 node
針對 Java 開發(fā)人員的 Dojo 概念
json-rpc-java (一)
JavaScript EE,第 2 部分: 用 Ajax 調(diào)用遠程 JavaScript 函數(shù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服