理解 Ajax 編程的基本知識(shí) 是重要的,但是如果正在構(gòu)建復(fù)雜的用戶界面,那么能夠在更高層次的抽象上工作也很重要。在 面向 Java 開發(fā)人員的 Ajax 系列的第 3 篇文章中,我在上個(gè)月的 Ajax 的數(shù)據(jù)序列化技術(shù) 基礎(chǔ)之上,介紹一種可以避免繁瑣的 Java 對(duì)象序列化細(xì)節(jié)的技術(shù)。
在 上一篇文章 中,我介紹了如何用 JavaScript 對(duì)象標(biāo)注(JSON)以一種在客戶機(jī)上容易轉(zhuǎn)化成 JavaScript 對(duì)象的格式對(duì)數(shù)據(jù)進(jìn)行序列化。有了這個(gè)設(shè)置,就可以用 JavaScript 代碼調(diào)用遠(yuǎn)程服務(wù),并在響應(yīng)中接收 JavaScript 對(duì)象圖,但是又不像遠(yuǎn)程過程調(diào)用。這一次,將學(xué)習(xí)如何更進(jìn)一步,使用一個(gè)框架,把從 JavaScript 客戶代碼對(duì)服務(wù)器端 Java 對(duì)象進(jìn)行遠(yuǎn)程調(diào)用的能力正式化。
DWR 是一個(gè)開放源碼的使用 Apache 許可協(xié)議的解決方案,它包含服務(wù)器端 Java 庫、一個(gè) DWR servlet 以及 JavaScript 庫。雖然 DWR 不是 Java 平臺(tái)上唯一可用的 Ajax-RPC 工具包,但是它是最成熟的,而且提供了許多有用的功能。請(qǐng)參閱 參考資料 ,在繼續(xù)學(xué)習(xí)之前下載 DWR。
從最簡單的角度來說,DWR 是一個(gè)引擎,可以把服務(wù)器端 Java 對(duì)象的方法公開給 JavaScript 代碼。使用 DWR 可以有效地從應(yīng)用程序代碼中把 Ajax 的全部請(qǐng)求-響應(yīng)循環(huán)消除掉。這意味著客戶端代碼再也不需要直接處理
XMLHttpRequest
對(duì)象或者服務(wù)器的響應(yīng)。不再需要編寫對(duì)象的序列化代碼或者使用第三方工具才能把對(duì)象變成 XML。甚至不再需要編寫 servlet 代碼把 Ajax 請(qǐng)求調(diào)整成對(duì) Java 域?qū)ο蟮恼{(diào)用。
DWR 是作為 Web 應(yīng)用程序中的 servlet 部署的。把它看作一個(gè)黑盒子,這個(gè) servlet 有兩個(gè)主要作用:首先,對(duì)于公開的每個(gè)類,DWR 動(dòng)態(tài)地生成包含在 Web 頁面中的 JavaScript。生成的 JavaScript 包含存根函數(shù),代表 Java 類上的對(duì)應(yīng)方法并在幕后執(zhí)行
XMLHttpRequest
。這些請(qǐng)求被發(fā)送給 DWR,這時(shí)它的第二個(gè)作用就是把請(qǐng)求翻譯成服務(wù)器端 Java 對(duì)象上的方法調(diào)用并把方法的返回值放在 servlet 響應(yīng)中發(fā)送回客戶端,編碼成 JavaScript。DWR 還提供了幫助執(zhí)行常見的用戶界面任務(wù)的 JavaScript 工具函數(shù)。
![]() ![]() |
![]()
|
在更詳細(xì)地解釋 DWR 之前,我要介紹一個(gè)簡單的示例場景。像在前一篇文章中一樣,我將采用一個(gè)基于在線商店的最小模型,這次包含一個(gè)基本的產(chǎn)品表示、一個(gè)可以包含產(chǎn)品商品的用戶購物車以及一個(gè)從數(shù)據(jù)存儲(chǔ)查詢產(chǎn)品的數(shù)據(jù)訪問對(duì)象(DAO)。
Item
類與前一篇文章中使用的一樣,但是不再實(shí)現(xiàn)任何手工序列化方法。圖 1 說明了這個(gè)簡單的設(shè)置:
圖 1. 說明 Cart、CatalogDAO 和 Item 類的類圖
在這個(gè)場景中,我將演示兩個(gè)非常簡單的用例。第一,用戶可以在目錄中執(zhí)行文本搜索并查看匹配的商品。第二,用戶可以添加商品到購物車中并查看購物車中商品的總價(jià)。
![]() ![]() |
![]()
|
DWR 應(yīng)用程序的起點(diǎn)是編寫服務(wù)器端對(duì)象模型。在這個(gè)示例中,我從編寫 DAO 開始,用它提供對(duì)產(chǎn)品目錄數(shù)據(jù)存儲(chǔ)的搜索功能。
CatalogDAO.java
是一個(gè)簡單的無狀態(tài)的類,有一個(gè)無參數(shù)的構(gòu)造函數(shù)。清單 1 顯示了我想要公開給 Ajax 客戶的 Java 方法的簽名:
清單 1. 通過 DWR 公開的 CatalogDAO 方法
|
接下來,我需要配置 DWR,告訴它 Ajax 客戶應(yīng)當(dāng)能夠構(gòu)建
CatalogDAO
并調(diào)用這些方法。我在清單 2 所示的 dwr.xml 配置文件中做這些事:
清單 2. 公開 CatalogDAO 方法的配置
|
dwr.xml 文檔的根元素是
dwr
。在這個(gè)元素內(nèi)是
allow
元素,它指定 DWR 進(jìn)行遠(yuǎn)程的類。
allow
的兩個(gè)子元素是
create
和
convert
。
create
元素告訴 DWR 應(yīng)當(dāng)公開給 Ajax 請(qǐng)求的服務(wù)器端類,并定義 DWR 應(yīng)當(dāng)如何獲得要進(jìn)行遠(yuǎn)程的類的實(shí)例。這里的
creator
屬性被設(shè)置為值
new
,這意味著 DWR 應(yīng)當(dāng)調(diào)用類的默認(rèn)構(gòu)造函數(shù)來獲得實(shí)例。其他的可能有:通過代碼段用 Bean 腳本框架(Bean Scripting Framework,BSF)創(chuàng)建實(shí)例,或者通過與 IOC 容器 Spring 進(jìn)行集成來獲得實(shí)例。默認(rèn)情況下,到 DWR 的 Ajax 請(qǐng)求會(huì)調(diào)用
creator
,實(shí)例化的對(duì)象處于頁面范圍內(nèi),因此請(qǐng)求完成之后就不再可用。在無狀態(tài)的
CatalogDAO
情況下,這樣很好。
create
的
javascript
屬性指定從 JavaScript 代碼訪問對(duì)象時(shí)使用的名稱。嵌套在
create
元素內(nèi)的
param
元素指定
creator
要?jiǎng)?chuàng)建的 Java 類。最后,
include
元素指定應(yīng)當(dāng)公開的方法的名稱。顯式地說明要公開的方法是避免偶然間允許訪問有害功能的良好實(shí)踐 —— 如果漏了這個(gè)元素,類的所有方法都會(huì)公開給遠(yuǎn)程調(diào)用。反過來,可以用
exclude
元素指定那些想防止被訪問的方法。
creator
負(fù)責(zé)公開用于 Web 遠(yuǎn)程的類和類的方法,
convertor
則負(fù)責(zé)這些方法的參數(shù)和返回類型。
convert
元素的作用是告訴 DWR 在服務(wù)器端 Java 對(duì)象表示和序列化的 JavaScript 之間如何轉(zhuǎn)換數(shù)據(jù)類型。
DWR 自動(dòng)地在 Java 和 JavaScript 表示之間調(diào)整簡單數(shù)據(jù)類型。這些類型包括 Java 原生類型和它們各自的類表示,還有 String、Date、數(shù)組和集合類型。DWR 也能把 JavaBean 轉(zhuǎn)換成 JavaScript 表示,但是出于安全性的原因,做這件事要求顯式的配置。
清單 2
中的
convert
元素告訴 DWR 用自己基于反射的 bean 轉(zhuǎn)換器處理
CatalogDAO
的公開方法返回的
Item
,并指定序列化中應(yīng)當(dāng)包含
Item
的哪個(gè)成員。成員的指定采用 JavaBean 命名規(guī)范,所以 DWR 會(huì)調(diào)用對(duì)應(yīng)的
get
方法。在這個(gè)示例中,我去掉了數(shù)字的
price
字段,而是包含了
formattedPrice
字段,它采用貨幣格式進(jìn)行顯示。
現(xiàn)在,我準(zhǔn)備把 dwr.xml 部署到 Web 應(yīng)用程序的
WEB-INF
目錄,在那里 DWR servlet 會(huì)讀取它。但是,在繼續(xù)之前,確保每件事都按照希望的那樣運(yùn)行是個(gè)好主意。
![]() ![]() |
![]()
|
如果
DWRServlet
的
web.xml
定義把
init-param
debug
設(shè)置為
true
,那么就啟用了 DWR 非常有幫助的測試模式。導(dǎo)航到
/{your-web-app}/dwr/
會(huì)把 DWR 配置的要進(jìn)行遠(yuǎn)程的類列表顯示出來。在其中點(diǎn)擊,會(huì)進(jìn)入指定類的狀態(tài)屏幕。
CatalogDAO
的 DWR 測試頁如圖 2 所示。除了提供粘貼到 Web 頁面的
script
標(biāo)記(指向 DWR 為類生成的 JavaScript)之外,這個(gè)屏幕還提供了類的方法列表。這個(gè)列表包括從類的超類繼承的方法,但是只有在
dwr.xml
中顯式地指定為遠(yuǎn)程的才標(biāo)記為可訪問。
圖 2. CatalogDAO 的 DWR 測試頁
可以在可訪問的方法旁邊的文本框中輸入?yún)?shù)值并點(diǎn)擊 Execute 按鈕調(diào)用方法。服務(wù)器的響應(yīng)將在警告框中用 JSON 標(biāo)注顯示出來,如果是簡單值,就會(huì)內(nèi)聯(lián)在方法旁邊直接顯示。這個(gè)測試頁非常有用。它們不僅允許檢查公開了哪個(gè)類和方法用于遠(yuǎn)程,還可以測試每個(gè)方法是否像預(yù)期的那樣工作。
如果對(duì)遠(yuǎn)程方法的工作感到滿意,就可以用 DWR 生成的 JavaScript 存根從客戶端代碼調(diào)用服務(wù)器端對(duì)象。
![]() ![]() |
![]()
|
遠(yuǎn)程 Java 對(duì)象方法和對(duì)應(yīng)的 JavaScript 存根函數(shù)之間的映射很簡單。通用的形式是
JavaScriptName.methodName(methodParams ..., callBack)
,其中
JavaScriptName
是
creator
的
javascript
屬性指定的名稱,
methodParams
代表 Java 方法的
n
個(gè)參數(shù),
callback
是要用 Java 方法的返回值調(diào)用的 JavaScript 函數(shù)。如果熟悉 Ajax,可以看出這個(gè)回調(diào)機(jī)制是
XMLHttpRequest
異步性的常用方式。
在示例場景中,我用清單 3 中的 JavaScript 函數(shù)執(zhí)行搜索,并用搜索結(jié)果更新用戶界面。這個(gè)清單還使用來自 DWR 的
util.js
的便捷函數(shù)。要特別說明的是名為
$()
的 JavaScript 函數(shù),可以把它當(dāng)作
document.getElementById()
的加速版。錄入它當(dāng)然更容易。如果您使用過 JavaScript 原型庫,應(yīng)當(dāng)熟悉這個(gè)函數(shù)。
清單 3. 從客戶機(jī)調(diào)用遠(yuǎn)程的 findItems()
|
在上面的
searchFormSubmitHandler()
函數(shù)中,我們感興趣的代碼當(dāng)然是
catalog.findItems(searchexp, displayItems);
。這一行代碼就是通過網(wǎng)絡(luò)向 DWR servlet 發(fā)送
XMLHttpRequest
并用遠(yuǎn)程對(duì)象的響應(yīng)調(diào)用
displayItems()
函數(shù)所需要的全部內(nèi)容。
displayItems()
回調(diào)本身是由一個(gè)
Item
數(shù)組表示調(diào)用的。這個(gè)數(shù)組傳遞給
DWRUtil.addRows()
便捷函數(shù),同時(shí)還有要填充的表的 ID 和一個(gè)函數(shù)數(shù)組。表中每行有多少單元格,這個(gè)數(shù)組中就有多少個(gè)函數(shù)。按照順序使用來自數(shù)組的
Item
逐個(gè)調(diào)用每個(gè)函數(shù),并用返回的內(nèi)容填充對(duì)應(yīng)的單元格。
在這個(gè)示例中,我想讓商品表中的每一行都顯示商品的名稱、說明和價(jià)格,并在最后一列顯示商品的 Add to Cart 按鈕。清單 4 顯示了實(shí)現(xiàn)這一功能的單元格函數(shù)數(shù)組:
清單 4. 填充商品表的單元格函數(shù)數(shù)組
|
前三個(gè)函數(shù)只是返回 dwr.xml 中
Item
的
convertor
包含的字段內(nèi)容。最后一個(gè)函數(shù)創(chuàng)建一個(gè)按鈕,把
Item
的 ID 賦給它,并指定在點(diǎn)擊按鈕時(shí)應(yīng)當(dāng)調(diào)用名為
addToCartButtonHandler
的函數(shù)。這個(gè)函數(shù)是第二個(gè)用例的入口點(diǎn):向購物車中添加
Item
。
![]() ![]() |
![]()
|
![]() |
|
用戶購物車的 Java 表示基于
Map
。當(dāng)
Item
添加到購物車中時(shí),
Item
本身作為鍵被插入
Map
。
Map
中對(duì)應(yīng)的值是一個(gè)
Integer
,代表購物車中指定
Item
的數(shù)量。所以
Cart.java
有一個(gè)字段
contents
,聲明為
Map<Item,Integer>
。
使用復(fù)雜類型作為哈希鍵給 DWR 帶來一個(gè)問題 —— 在 JavaScript 中,數(shù)組的鍵必須是標(biāo)量的。所以,DWR 無法轉(zhuǎn)換
contents
Map
。但是,對(duì)于購物車用戶界面來說,用戶需要查看的只是每個(gè)商品的名稱和數(shù)量。所以我向
Cart
添加了一個(gè)名為
getSimpleContents()
的方法,它接受
contents
Map
并根據(jù)它構(gòu)建一個(gè)簡化的
Map<String,Integer>
,只代表每個(gè)
Item
的名稱和數(shù)量。這個(gè)用字符串作為鍵的 map 表示可以由 DWR 的轉(zhuǎn)換器轉(zhuǎn)換成 JavaScript。
客戶對(duì)
Cart
感興趣的其他字段是
totalPrice
,它代表購物車中所有商品的金額匯總。使用
Item
,我還提供了一個(gè)合成的成員叫作
formattedTotalPrice
,它是金額匯總的格式化好的
String
表示。
為了不讓客戶代碼對(duì)
Cart
做兩個(gè)調(diào)用(一個(gè)獲得內(nèi)容,一個(gè)獲得總價(jià)),我想把這些數(shù)據(jù)一次全都發(fā)給客戶。為了做到這一點(diǎn),我添加了一個(gè)看起來有點(diǎn)兒怪的方法,如清單 5 所示:
清單 5. Cart.getCart() 方法
|
雖然這個(gè)方法在普通的 Java 代碼中可能完全是多余的(因?yàn)樵谡{(diào)用這個(gè)方法時(shí),已經(jīng)有對(duì)
Cart
的引用),但它允許 DWR 客戶讓
Cart
把自己序列化成 JavaScript。
除了
getCart()
,需要遠(yuǎn)程化的另一個(gè)方法是
addItemToCart()
。這個(gè)方法接受目錄 Item 的 ID 的
String
表示,把這個(gè)商品添加到
Cart
中并更新總價(jià)。方法還返回
Cart
,這樣客戶代碼在一個(gè)操作中就能更新
Cart
的內(nèi)容并接收購物車的新狀態(tài)。
清單 6 是擴(kuò)展的 dwr.xml 配置文件,包含
Cart
類進(jìn)行遠(yuǎn)程所需要的額外配置:
清單 6. 修改過的 dwr.xml 包含了 Cart 類
|
在這個(gè)版本的
dwr.xml
中,我添加了
Cart
的
creator
和
convertor
。
create
元素指定應(yīng)當(dāng)把
addItemToCart()
和
getCart()
方法遠(yuǎn)程化,而且重要的是,生成的
Cart
實(shí)例應(yīng)當(dāng)放在用戶的會(huì)話中。所以,購物車的內(nèi)容在用戶的請(qǐng)求之間會(huì)保留。
Cart
的
convert
元素是必需的,因?yàn)檫h(yuǎn)程的
Cart
方法返回的是
Cart
本身。在這里我指定在
Cart
的序列化 JavaScript 形式中應(yīng)當(dāng)存在的成員是
simpleContents
這個(gè)圖和
formattedTotalPrice
這個(gè)字符串。
如果對(duì)這覺得有點(diǎn)兒不明白,那么只要記住
create
元素指定的是 DWR 客戶可以調(diào)用的
Cart
服務(wù)器端方法,而
convert
元素指定在
Cart
的 JavaScript 序列化形式中包含的成員。
現(xiàn)在可以實(shí)現(xiàn)調(diào)用
Cart
的遠(yuǎn)程方法的客戶端代碼了。
![]() ![]() |
![]()
|
首先,當(dāng)商店的 Web 頁首次裝入時(shí),我想檢查保存在會(huì)話中的
Cart
的狀態(tài),看是否已經(jīng)有一個(gè)購物車了。這是必需的,因?yàn)橛脩艨赡芤呀?jīng)向
Cart
中添加了商品,然后刷新了頁面或者導(dǎo)航到其他地方之后又返回來。在這些情況下,重新載入的頁面需要用會(huì)話中的
Cart
數(shù)據(jù)對(duì)自己進(jìn)行同步。我可以在頁面的 onload 函數(shù)中用一個(gè)調(diào)用做到這一點(diǎn),就像這樣:
Cart.getCart(displayCart)
。請(qǐng)注意
displayCart()
是一個(gè)回調(diào)函數(shù),由服務(wù)器返回的
Cart
響應(yīng)數(shù)據(jù)調(diào)用。
如果
Cart
已經(jīng)在會(huì)話中,那么
creator
會(huì)檢索它并調(diào)用它的
getCart()
方法。如果會(huì)話中沒有
Cart
,那么
creator
會(huì)實(shí)例化一個(gè)新的,把它放在會(huì)話中,并調(diào)用
getCart()
方法。
清單 7 顯示了
addToCartButtonHandler()
函數(shù)的實(shí)現(xiàn),當(dāng)點(diǎn)擊商品的
Add to Cart
按鈕時(shí)會(huì)調(diào)用這個(gè)函數(shù):
清單 7. addToCartButtonHandler() 實(shí)現(xiàn)
|
由 DWR 負(fù)責(zé)所有通信,所以客戶上的添加到購物車行為就是一個(gè)函數(shù)。清單 8 顯示了這個(gè)示例的最后一部分 ——
displayCart()
回調(diào)的實(shí)現(xiàn),它用
Cart
的狀態(tài)更新用戶界面:
清單 8. displayCart() 實(shí)現(xiàn)
|
在這里重要的是要記住,
simpleContents
是一個(gè)把
String
映射到數(shù)字的 JavaScript 數(shù)組。每個(gè)字符串都是一個(gè)商品的名稱,關(guān)聯(lián)數(shù)組中的對(duì)應(yīng)數(shù)字就是購物車中該商品的數(shù)量。所以表達(dá)式
cart.simpleContents[item] + " x " + item
可能就會(huì)計(jì)算出 “
2 x Oolong 128MB CF Card
” 這樣的結(jié)果。
圖 3 顯示了這個(gè)基于 DWR 的 Ajax 應(yīng)用程序的使用情況:顯示了通過搜索檢索到的商品,并在右側(cè)顯示用戶的購物車:
圖 3. 基于 DWR 的 Ajax 商店應(yīng)用程序的使用情況
![]() ![]() |
![]()
|
![]() |
|
現(xiàn)在可以看出用 DWR 實(shí)現(xiàn)由 Java 支持的 Ajax 應(yīng)用程序有多么容易了。雖然示例場景很簡單,我實(shí)現(xiàn)用例的手段也盡可能少,但是不應(yīng)因此而低估 DWR 引擎相對(duì)于自己設(shè)計(jì) Ajax 應(yīng)用程序可以節(jié)約的工作量。在前一篇文章中,我介紹了手工設(shè)計(jì) Ajax 請(qǐng)求和響應(yīng)、把 Java 對(duì)象圖轉(zhuǎn)化成 JSON 表示的全部步驟,在這篇文章中,DWR 替我做了所有這些工作。我只編寫了不到 50 行 JavaScript 就實(shí)現(xiàn)了客戶機(jī),而在服務(wù)器端,我需要做的所有工作就是給常規(guī)的 JavaBean 加上一些額外方法。
當(dāng)然,每種技術(shù)都有它的不足。同任何 RPC 機(jī)制一樣,在 DWR 中,可能很容易忘記對(duì)于遠(yuǎn)程對(duì)象進(jìn)行的每個(gè)調(diào)用都要比本地函數(shù)調(diào)用昂貴得多。DWR 在隱藏 Ajax 的機(jī)械性方面做得很好,但是重要的是要記住網(wǎng)絡(luò)并不是透明的 —— 進(jìn)行 DWR 調(diào)用會(huì)有延遲,所以應(yīng)用程序的架構(gòu)應(yīng)當(dāng)讓遠(yuǎn)程方法的粒度比較粗。正是為了這個(gè)目的,
addItemToCart()
才返回
Cart
本身。雖然讓
addItemToCart()
作為一個(gè) void 方法可能更自然,但是這樣的話對(duì)它的每個(gè) DWR 調(diào)用后面都必須跟著一個(gè)
getCart()
調(diào)用以檢索修改后的
Cart
狀態(tài)。
對(duì)于延遲,DWR 在調(diào)用的批處理中有自己的解決方案(請(qǐng)參閱側(cè)欄的 調(diào)用批處理 )。如果不能為應(yīng)用程序提供適當(dāng)粗粒度的 Ajax 接口,那么只要有可能把多個(gè)遠(yuǎn)程調(diào)用組合到一個(gè) HTTP 請(qǐng)求中,就請(qǐng)使用調(diào)用批處理。
從實(shí)質(zhì)上看,DWR 在客戶端和服務(wù)器端代碼間形成了緊密的耦合,這有許多含義:首先,遠(yuǎn)程方法 API 的變化需要在 DWR 存根調(diào)用的 JavaScript 上反映出來。第二(也是最明顯的),這種耦合會(huì)造成對(duì)客戶端的考慮會(huì)滲入服務(wù)器端代碼。例如,因?yàn)椴皇撬?Java 類型都能轉(zhuǎn)化成 JavaScript,所以有時(shí)有必要給 Java 對(duì)象添加額外方法,好讓它能夠更容易地遠(yuǎn)程化。在示例場景中,我通過把
getSimpleContents()
方法添加到
Cart
來解決這個(gè)問題。我還添加了
getCart()
方法,它在 DWR 場景中是有用的,但在其他場景中則完全是多余的。由于遠(yuǎn)程對(duì)象粗粒度 API 的需要以及把某些 Java 類型轉(zhuǎn)化成 JavaScript 的問題,所以可以看到遠(yuǎn)程 JavaBean 會(huì)被那些只對(duì) Ajax 客戶有用的方法“污染”。
為了克服這個(gè)問題,可以使用包裝器類把額外的特定于 DWR 的方法添加到普通 JavaBean。這意味著 JavaBean 類的 Java 客戶可能看不到與遠(yuǎn)程相關(guān)聯(lián)的額外的毛病,而且也允許給遠(yuǎn)程方法提供更友好的名稱 —— 例如用
getPrice()
代替
getFormattedPrice()
。圖 4 顯示的
RemoteCart
類對(duì)
Cart
進(jìn)行了包裝,添加了額外的 DWR 功能:
圖 4. RemoteCart 為遠(yuǎn)程功能對(duì) Cart 做了包裝
最后,需要記住:DWR Ajax 調(diào)用是異步的,所以不要期望它們會(huì)按照分派的順序返回。在示例代碼中我忽略了這個(gè)小問題,但是在這個(gè)系列的第一篇文章中,我演示了如何為響應(yīng)加時(shí)間戳,以此作為保證數(shù)據(jù)到達(dá)順序的一種簡單手段。
![]() ![]() |
![]()
|
正如所看到的,DWR 提供了許多東西 —— 它允許迅速而簡單地創(chuàng)建到服務(wù)器端域?qū)ο蟮?Ajax 接口,而不需要編寫任何 servlet 代碼、對(duì)象序列化代碼或客戶端
XMLHttpRequest
代碼。使用 DWR 部署到 Web 應(yīng)用程序極為簡單,而且 DWR 的安全性特性可以與 J2EE 基于角色的驗(yàn)證系統(tǒng)集成。但是 DWR 并不是對(duì)于任何一種應(yīng)用程序架構(gòu)都適合,所以在設(shè)計(jì)域?qū)ο蟮?API 時(shí)需要做些考慮。
如果想學(xué)習(xí)用 DWR 進(jìn)行 Ajax 的利弊的更多內(nèi)容,最好的方式就是下載并開始實(shí)踐。DWR 有許多我沒有介紹的特性, 文章源代碼 是把 DWR 投入使用的一個(gè)良好起點(diǎn)。請(qǐng)參閱 參考資料 ,學(xué)習(xí)關(guān)于 Ajax、DWR 和相關(guān)技術(shù)的更多內(nèi)容。
這個(gè)系列中要指出的最重要的一點(diǎn)是:對(duì)于 Ajax 應(yīng)用程序,沒有包治百病的解決方案。Ajax 是一個(gè)快速發(fā)展的領(lǐng)域,不斷有新技術(shù)涌現(xiàn)。在這個(gè)系列的三篇文章中,我的重點(diǎn)在于帶您開始在 Ajax 應(yīng)用程序的 Web 層中利用 Java 技術(shù) —— 不管是選擇基于
XMLHttpRequest
的帶有對(duì)象序列化框架的技術(shù),還是選擇 DWR 這樣的更高級(jí)抽象。請(qǐng)?jiān)诤罄m(xù)幾個(gè)月中留意面向 Java 開發(fā)人員介紹 Ajax 的文章。
![]() ![]() |
![]()
|
描述 名字 大小 下載方法
DWR source code | j-ajax3dwr.zip | 301 KB | FTP |
![]() |
||||
![]() |
關(guān)于下載方法的信息 |
![]() |
![]() |
Get Adobe? Reader? |
![]() ![]() |
![]()
|
學(xué)習(xí)
-
您可以參閱本文在 developerWorks 全球站點(diǎn)上的
英文原文
。
-
“
Call SOAP Web services with AJAX, Part 1: Build the Web services client
” (James Snell,developerWorks,2005 年 10 月):用 Ajax 實(shí)現(xiàn) SOAP Web 服務(wù)客戶機(jī)。
-
“
面向 Java 開發(fā)人員的 Ajax: Ajax 的 Java 對(duì)象序列化
” (Philip McCarthy,developerWorks,2005 年 10 月):學(xué)習(xí)在 Ajax 應(yīng)用程序中進(jìn)行數(shù)據(jù)序列化的技術(shù)。
-
“
面向 Java 開發(fā)人員的 Ajax: 構(gòu)建動(dòng)態(tài)的 Java 應(yīng)用程序
” (Philip McCarthy,developerWorks,2005 年 9 月):使用 Ajax 的第一步。
-
DWR Handbook
:對(duì) Ajax 和 DWR 的介紹。
-
“
Developing AJAX Applications the Easy Way
” (Java.net,2005 年 8 月):DWR 的創(chuàng)造者 Joe Walker 介紹如何編寫簡單的 Ajax 聊天服務(wù)器。
-
請(qǐng)參閱教程
An alternative to generating Ajax code with Java is using the Simple Ajax Toolkit (Sajax)
,學(xué)習(xí)如何從 Sajax 起步。
- Java 技術(shù)專區(qū) :數(shù)百篇關(guān)于 Java 編程各方面的文章。
獲得產(chǎn)品和技術(shù)
-
下載 DWR
:得到最新的 DWR jar 發(fā)行包。
-
JSON-RPC-Java
:用于 Java 的另一個(gè) Ajax-RPC 引擎。
討論
-
參與論壇討論
。
-
DWR's Java.net pages
:訂閱 DWR 的郵件列表。
-
developerWorks blogs
:加入 developerWorks 社區(qū)。
![]() ![]() |
![]()
|
![]() |
||
|
![]() |
Philip McCarthy 是一位軟件開發(fā)顧問,專攻 Java 和 Web 技術(shù)。他目前在位于 Bristol 的 HP 試驗(yàn)室從事 Hewlett Packard 數(shù)字媒體平臺(tái)的工作 。在最近幾年中,Phil 開發(fā)了多個(gè)采用異步服務(wù)器通信和 DOM 腳本的富 Web 客戶端。他很高興我們現(xiàn)在有了一個(gè)針對(duì)它們的名稱。可以通過 Phil 的電子郵件 philmccarthy@gmail.com 與他聯(lián)系。 |
==================榕樹轉(zhuǎn)貼自:http://www-128.ibm.com==================== |
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
