本人僅出于學(xué)習目的翻譯,完整無(wú)誤文章請參見(jiàn)原文!
面向Java開(kāi)發(fā)者的Ajax:構建動(dòng)態(tài)的Java應用程序
Ajax鋪設了更好的開(kāi)發(fā)Web應用的道路
級別:中級
Philip McCarthy (mailto:philmccarthy@gmail.com?subject=Build dynamic Java applications), Software Development Consultant, Independent Consultant
9月20日2005年
頁(yè)面重載提出了一個(gè)在Web應用開(kāi)發(fā)中最大的可用性障礙,對于java開(kāi)發(fā)來(lái)說(shuō)也是一個(gè)重大的挑戰。在本系列中,作者Philip McCarthy介紹了通過(guò)后臺通道的方法來(lái)創(chuàng )建動(dòng)態(tài)Web應用的經(jīng)驗。Ajax(Asynchronous JavaScript and XML)是一個(gè)結合了Java技術(shù)、XML、以及JavaScript的編程技術(shù),可以讓你構建基于Java技術(shù)的Web應用,并打破了使用頁(yè)面重載的慣例。
Ajax,異步JavaScript與XML,是使用客戶(hù)端腳本與Web服務(wù)器交換數據的Web應用開(kāi)發(fā)方法。這樣,Web頁(yè)面不用打斷交互流程進(jìn)行重新加裁,就可以動(dòng)態(tài)地更新。使用Ajax,你可以創(chuàng )建接近本地桌面應用的,直接的、高可用的、更豐富的、更動(dòng)態(tài)的Web用戶(hù)接口界面。
Ajax不是一個(gè)技術(shù),它更像是一個(gè)模式—標志并描述有用的設計技巧的一種方法。對于剛了解它的許多開(kāi)發(fā)人員來(lái)說(shuō),它是一種新的感覺(jué),但是實(shí)現Ajax的所有組件都已存在了許多年。當前的熱鬧是因為在2004與2005年出現了一些基于Ajax的非常動(dòng)態(tài)的WebUI,尤其是Google的GMail與Maps應用系統、與照片共享網(wǎng)站Flickr。這些UI充分地使用了后臺通道,也被一些開(kāi)發(fā)者稱(chēng)為“Web 2.0”,并導致了大家對Ajax應用興趣的猛漲。
在本系列中,我將給出所有你需要的開(kāi)發(fā)你自己的Ajax應用的工具。在這第一篇文章中,我將解釋在Ajax背后的概念,示范為基于Web的應用系統創(chuàng )建一個(gè)Ajax接口的基本步驟。我將使用示例代碼來(lái)示范實(shí)現Ajax動(dòng)態(tài)接口的服務(wù)器端Java代碼與客戶(hù)端JavaScript腳本。最后,我將指出一些Ajax方法中易犯的錯誤,以及在創(chuàng )建Ajax應用時(shí)應該考慮的廣泛范圍內的可用性與易訪(fǎng)問(wèn)性方面的問(wèn)題。
一個(gè)更好的購物車(chē)
你可以使用Ajax來(lái)加強傳統的Web應用,通過(guò)消除頁(yè)面載入來(lái)使交互更流暢。為了示范它,我將使用一個(gè)簡(jiǎn)單的,能動(dòng)態(tài)更新加入的物品購物車(chē)。結合一個(gè)在線(xiàn)商店,這個(gè)方法可以不用等待點(diǎn)擊后的頁(yè)面重載,而讓我們繼續瀏覽并挑選物品到購物車(chē)中。雖然,本文中的代碼針對購物車(chē)例子,但其中展示的技術(shù)可以用到其它的Ajax應用中。列表1中展示了購物車(chē)示例所使用的HTML代碼。在整篇文章中,我都將會(huì )引用到這些HTML代碼。
列表1:購物車(chē)示例的相關(guān)代碼片斷
<!-- Table of products from store‘s catalog, one row per item -->
<th>Name</th> <th>Description</th> <th>Price</th> <th></th>
...
<tr>
<!-- Item details -->
<td>Hat</td> <td>Stylish bowler hat</td> <td>$19.99</td>
<td>
<!-- Click button to add item to cart via Ajax request -->
<button onclick="addToCart(‘hat001‘)">Add to Cart</button>
</td>
</tr>
...
<!-- Representation of shopping cart, updated asynchronously -->
<ul id="cart-contents">
<!-- List-items will be added here for each item in the cart -->
</ul>
<!-- Total cost of items in cart displayed inside span element -->
Total cost: <span id="total">$0.00</span>
Ajax處理過(guò)程
一個(gè)Ajax交互從一個(gè)稱(chēng)為XMLHttpRequest的JavaScript對象開(kāi)始。如同名字所暗示的,它允許一個(gè)客戶(hù)端腳本來(lái)執行HTTP請求,并且將會(huì )解析一個(gè)XML格式的服務(wù)器響應。Ajax處理過(guò)程中的第一步是創(chuàng )建一個(gè)XMLHttpRequest實(shí)例。使用HTTP方法(GET或POST)來(lái)處理請求,并將目標URL設置到XMLHttpRequest對象上。
現在,記住Ajax如何首先處于異步處理狀態(tài)?當你發(fā)送HTTP請求,你不希望瀏覽器掛起并等待服務(wù)器的響應,取而代之的是,你希望通過(guò)頁(yè)面繼續響應用戶(hù)的界面交互,并在服務(wù)器響應真正到達后處理它們。要完成它,你可以向XMLHttpRequest注冊一個(gè)回調函數,并異步地派發(fā)XMLHttpRequest請求??刂茩囫R上就被返回到瀏覽器,當服務(wù)器響應到達時(shí),回調函數將會(huì )被調用。
在Java Web服務(wù)器上,到達的請求與任何其它HttpServletRequest一樣。在解析請求參數后,servlet執行必需的應用邏輯,將響應序列化到XML中,并將它寫(xiě)回HttpServletResponse。
回到客戶(hù)端,注冊在XMLHttpRequest上的回調函數現在會(huì )被調用來(lái)處理由服務(wù)器返回的XML文檔。最后,通過(guò)更新用戶(hù)界面來(lái)響應服務(wù)器傳輸過(guò)來(lái)數據,使用JavaScript來(lái)操縱頁(yè)面的HTML DOM。圖1是Ajax處理過(guò)程的一個(gè)時(shí)序圖。
圖1:Ajax處理過(guò)程


現在,你應該對Ajax處理過(guò)程有了一個(gè)高層視圖。我將進(jìn)入其中的每一步看看更細節的內容。如果你找不到自己的位置時(shí),就回頭再看看圖1,加—因為Ajax方法的異步本質(zhì),所以時(shí)序圖并不是筆直向前的。
發(fā)送一個(gè)XMLHttpRequest
我將從Ajax時(shí)序圖的起點(diǎn)開(kāi)始:從瀏覽器創(chuàng )建并發(fā)送一個(gè)XMLHttpRequest。不幸的是,在不同的瀏覽器中創(chuàng )建XMLHttpRequest的方法都不一樣。列表2中示例的JavaScript函數消除了這些與瀏覽器種類(lèi)相關(guān)的問(wèn)題,正確檢測與當前瀏覽器相關(guān)的方法,并返回一個(gè)可以使用的XMLHttpRequest。最好將它看成備用代碼,將它簡(jiǎn)單拷貝到你的JavaScript庫中,在需要一個(gè)XMLHttpRequest時(shí)使用它即可。
列表2:跨瀏覽器創(chuàng )建一個(gè)XMLHttpRequest
/*
* 返回一個(gè)新建的XMLHttpRequest對象,若瀏覽器不支持則失敗
*/
function newXMLHttpRequest() {
var xmlreq = false;
if (window.XMLHttpRequest) {
// 在非Microsoft瀏覽器中創(chuàng )建XMLHttpRequest對象
xmlreq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
//通過(guò)MS ActiveX創(chuàng )建XMLHttpRequest
try {
// 嘗試按新版InternetExplorer方法創(chuàng )建
xmlreq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e1) {
// 創(chuàng )建請求的ActiveX對象失敗
try {
// 嘗試按老版InternetExplorer方法創(chuàng )建
xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
// 不能通過(guò)ActiveX創(chuàng )建XMLHttpRequest
}
}
}
return xmlreq;
}
稍后,我將討論如何對待不支持XMLHttpReauest的瀏覽器的一些技巧?,F在,列表2中展示的示例函數將總是可以返回一個(gè)XMLHttpReauest實(shí)例。
回到購物車(chē)例子的場(chǎng)景中,只要用戶(hù)針對某一個(gè)目錄條目點(diǎn)擊了Add to Cart按鈕,我就要調用一個(gè)Ajax交互。名為addToCart()的onclick函數通過(guò)Ajax調用(如列表1中所示)來(lái)負責更新購物車(chē)的狀態(tài)。在列表3中,addToCart()要做的第一件事就是通過(guò)調用newXMLHttpReauest函數(如列表2中所示)來(lái)獲取一個(gè)XMLHttpRequest的實(shí)例,并且注冊一個(gè)回調函數來(lái)接受服務(wù)器響應(我將在稍后詳細解釋?zhuān)垍⒁?jiàn)列表6)。
因為,此請求將會(huì )修改服務(wù)器狀態(tài),我將使用一個(gè)HTTP POST來(lái)處理它。通過(guò)POST傳送數據需要三個(gè)步驟:首先,我需要打開(kāi)一個(gè)到進(jìn)行通訊的服務(wù)器資源的POST連接—在現在例子中是一個(gè)URL映射為cart.do的服務(wù)器端servlet。下一步,設置XMLHttpRequest的頭信息,以標志請求的內容為form-encoded。最后,將form-encoded數據作為請求體,并發(fā)送此請求。
列表3中集中展示了這些步驟。
列表3:發(fā)送一個(gè)添加到購物車(chē)XMLHttpRequest
/*
* 通過(guò)產(chǎn)品編碼,在購物車(chē)中添加一個(gè)條目
* itemCode – 需要添加條目的產(chǎn)品編碼
*/
function addToCart(itemCode) {
// 獲取一個(gè)XMLHttpRequest實(shí)例
var req = newXMLHttpRequest();
// 設置用來(lái)從請求對象接收回調通知的句柄函數
var handlerFunction = getReadyStateHandler(req, updateCart);
req.onreadystatechange = handlerFunction;
// 打開(kāi)一個(gè)聯(lián)接到購物車(chē)servlet的HTTP POST聯(lián)接
// 第三個(gè)參數表示請求是異步的
req.open("POST", "cart.do", true);
// 指示請求體包含form數據
req.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
// 發(fā)送標志需要添加到購物車(chē)中條目的form-encoded數據
req.send("action=add&item="+itemCode);
}
結合以上內容,你可以了解到Ajax處理過(guò)程的第一部分—就是在客戶(hù)端創(chuàng )建并發(fā)送HTTP請求。下一步是用來(lái)處理請求的Java Servlet代碼。
Servlet請求處理
通過(guò)一個(gè)servlet來(lái)處理XMLHttpRequest與處理一個(gè)來(lái)自瀏覽器的普通的HTTP請求基本上相似??梢酝ㄟ^(guò)調用HttpServletRequest.getParameter()來(lái)獲取由POST請求體傳送過(guò)來(lái)的form-encoded數據。Ajax請求也與普通的WEB請求樣都成為此應用同一HttpSession會(huì )話(huà)進(jìn)程的一部分。這對于購物車(chē)例子來(lái)說(shuō)很有肜,因為我們可以通過(guò)會(huì )話(huà)將多個(gè)請求的狀態(tài)都保存到同一個(gè)JavaBean購物車(chē)對象中,并可以序列化。
列表4是處理Ajax請求并更新購物車(chē)的簡(jiǎn)單servlet的代碼片斷。從用戶(hù)會(huì )話(huà)中檢索出一個(gè)Cart Bean,并按請求的參數更新它。之后Cart Bean被序列化到XML,并被寫(xiě)回ServletRespone。注意,一定要將響應內容的類(lèi)型設置為application/xml,否則,XMLHttpRequest將不能將響應內容解析為一個(gè)XML DOM。
列表4:處理Ajax請求的Servlet代碼
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws java.io.IOException {
Cart cart = getCartFromSession(req);
String action = req.getParameter("action");
String item = req.getParameter("item");
if ((action != null)&&(item != null)) {
// 在購物車(chē)中添加或移除一個(gè)條目
if ("add".equals(action)) {
cart.addItem(item);
} else if ("remove".equals(action)) {
cart.removeItems(item);
}
}
// 將購物車(chē)狀態(tài)序列化到XML
String cartXml = cart.toXml();
// 將XML寫(xiě)入response.
res.setContentType("application/xml");
res.getWriter().write(cartXml);
}
列表5展示了由Cart.toXml()方法生成的XML。注意到生成的cart元素的屬性,是一個(gè)通過(guò)System.currentTimeMillis()生成的時(shí)間戳。
列表5:Cart對象序列化得到的XML
<?xml version="1.0"?>
<cart generated="1123969988414" total="$171.95">
<item code="hat001">
<name>Hat</name>
<quantity>2</quantity>
</item>
<item code="cha001">
<name>Chair</name>
<quantity>1</quantity>
</item>
<item code="dog001">
<name>Dog</name>
<quantity>1</quantity>
</item>
</cart>
如果你觀(guān)察一下下載站點(diǎn)提供的例子應用源碼中的Cart.java,你將會(huì )看到它通過(guò)簡(jiǎn)單地追加字符串來(lái)生成XML。對于本例子來(lái)說(shuō),它已經(jīng)足夠了,我將會(huì )在本系統文章的以后一期中介紹一些更好的方法。
現在你知道了CartServlet如何響應一個(gè)XMLHttpRequest。下一步是返回到客戶(hù)端,如何用服務(wù)器響應來(lái)更新頁(yè)面狀態(tài)。
通過(guò)JavaScript來(lái)處理服務(wù)器響應
XMLHttpRequest的readyState屬性是一個(gè)給出請求生命周期狀態(tài)的數字值。它從表示“未初始化”的0變化到表示“完成”的4。每次readyState改變時(shí),都會(huì )引發(fā)readystatechange事件,通過(guò)onreadystatechange屬性配置回調處理函數將會(huì )被調用。
在列表3中,你已看到通過(guò)調用函數getReadyStateHandler()創(chuàng )建了一個(gè)處理函數,并被配置給onreadystatechange屬性。getReadyStateHandler()使用了這樣的事實(shí):函數是JavaScript中的主要對象。這意味著(zhù),函數可以作為參數被傳遞到其它函數,并且可以創(chuàng )建并返回其它函數。getReadystateHandler()要做是就是返回一個(gè)函數,來(lái)檢查XMLHttpRequet是否已經(jīng)完成處理,并傳遞XML服務(wù)器響應到由調用者指定的處理函數。列表6是getReadyStateHandler()的代碼。
列表6:函數getReadyStateHandler()
/*
* Returns a function that waits for the specified XMLHttpRequest
* to complete, then passes its XML response to the given handler function.
* req - The XMLHttpRequest whose state is changing
* responseXmlHandler - Function to pass the XML response to
*/
function getReadyStateHandler(req, responseXmlHandler) {
// 返回一個(gè)監聽(tīng)XMLHttpRequest實(shí)例的匿名函數
return function () {
// 如果請求的狀態(tài)是“完成”
if (req.readyState == 4) {
// 檢查是否成功接收了服務(wù)器響應
if (req.status == 200) {
// 將載有響應信息的XML傳遞到處理函數
responseXmlHandler(req.responseXML);
} else {
// 有HTTP問(wèn)題發(fā)生
alert("HTTP error: "+req.status);
}
}
}
}
HTTP狀態(tài)碼
在列表6中,XMLHttpRequest的status屬性被測試用來(lái)確定請求是否成功完成。當處理簡(jiǎn)單的GET與POST請求,你可以認為只要不是200(OK)的狀態(tài)就表示發(fā)生了錯誤。若服務(wù)器發(fā)送了一個(gè)重定向響應(例如,301或302),瀏覽器會(huì )透明地完成重定向并從新位置獲取相應的資源;XMLHttpRequest不會(huì )看到重定向狀態(tài)碼。同時(shí),瀏覽器自動(dòng)添加一個(gè)緩存控制:對于所有XMLHttpRequest都使用no-cache header,這樣客戶(hù)端代碼就可以不用處理304(not-modified)響應。
關(guān)于getReadyStateHandler()
getReadyStateHandler()是相對比較復雜的一段代碼,特別當你不能熟悉閱讀JavaScript時(shí)。折中方案是在你的JavaScript庫中包含此函數,你可以簡(jiǎn)單地處理Ajax服務(wù)器響應,而不用去注意XMLHttpRequest的內部細節。重要是你自己要理解在代碼中如何使用getReadyStateHandler()。
在列表3中,你看到getReadyStateHandler()被這樣調用:
handlerFunction=getReadyStateHandler(req,updateCart)。
由它返回的函數將會(huì )檢查在req變量中的XMLHttpRequest是否已完成,并調用由updateCart指定的回調方法處理響應XML。
提取購物車(chē)數據
列表7中展示了updateCart()中的代碼。此函數使用DOM來(lái)解析購物車(chē)XML文檔,并更新WEB頁(yè)面(參見(jiàn)列表1)來(lái)反映新的購物車(chē)內容。注意對用來(lái)提取數據的XML DOM的調用。Cart元素上生成的屬性,即序列化時(shí)生成的時(shí)間戳,通過(guò)檢測它可以保證不會(huì )用老的數據來(lái)覆蓋新的購物車(chē)數據。Ajax請求天生就是異步的,通過(guò)這個(gè)檢測可以有效避免在過(guò)程外到達的服務(wù)器響應的干擾。
列表7:更新頁(yè)面來(lái)反映出購物車(chē)XML文檔內容
function updateCart(cartXML) {
// 從文檔中獲取根元素“cart”
var cart = cartXML.getElementsByTagName("cart")[0];
// 保證此文檔是最新的
var generated = cart.getAttribute("generated");
if (generated > lastCartUpdate) {
lastCartUpdate = generated;
// 清除HTML列表,用來(lái)顯示購物車(chē)內容
var contents = document.getElementById("cart-contents");
contents.innerHTML = "";
// 在購物車(chē)內按條目循環(huán)
var items = cart.getElementsByTagName("item");
for (var I = 0 ; I < items.length ; I++) {
var item = items[I];
// 從name與quantity元素中提取文本節點(diǎn)
var name = item.getElementsByTagName("name")[0].firstChild.nodeValue;
var quantity = item.getElementsByTagName("quantity")[0].firstChild.nodeValue;
// 為條目創(chuàng )建并添加到HTML列表中
var li = document.createElement("li");
li.appendChild(document.createTextNode(name+" x "+quantity));
contents.appendChild(li);
}
}
// 更新購物車(chē)的金額累計
document.getElementById("total").innerHTML = cart.getAttribute("total");
}
到現在,關(guān)于Ajax處理過(guò)程的教程已經(jīng)結束,也許你想讓?xiě)眠\行起來(lái),并看看它的實(shí)際運作(參見(jiàn)下載部分)。這個(gè)例子非常簡(jiǎn)單,有非常大的改進(jìn)的余地。比如,我在服務(wù)器端代碼中包含了從購物車(chē)中移除條目的代碼,但從客戶(hù)端UI中沒(méi)有訪(fǎng)問(wèn)的途徑。作為一個(gè)練習,嘗試在現有的JavaScript基礎上實(shí)際這個(gè)功能。
使用Ajax的挑戰
與任何技術(shù)一樣,使用Ajax在相當多的方面都可能范錯誤。我在這兒討論的問(wèn)題目前都缺少解決方案,并將會(huì )隨著(zhù)Ajax的成熟而解決或提高。隨著(zhù)開(kāi)發(fā)Ajax應用經(jīng)驗的不斷獲取,開(kāi)發(fā)者社區中將會(huì )出現最好的實(shí)踐經(jīng)驗與指導方針。
XMLHttpRequest的有效性
Ajax開(kāi)發(fā)者面對的一個(gè)最大問(wèn)題是當XMLHttpRequest不可用時(shí)如何反應。雖然大部分現代瀏覽器支持XMLHttpRequest,但還是有少量的用戶(hù),他們的瀏覽器不能支持,或由于瀏覽器安全設置而阻止對XMLHttpRequest的使用。若你的Web應用發(fā)布于公司內部的Intranet上,你很可能可以指定支持哪種瀏覽器,并可以確保XMLHttpRequest是可用的。若你在公共WEB上發(fā)布,則你必須意識到由于假定XMLHttpRequest是可用的,所有就阻止了老瀏覽器、手持設備瀏覽器等等用戶(hù)來(lái)使用你的系統。
然而,你應該盡力保證應用系統“正常降級”使用,在系統中保留適用于不支持XMLHttpRequest的瀏覽器的功能。在購物車(chē)例子中,最好的方法是有一個(gè)Add to Cart按鈕,可以進(jìn)行常規的提交處理,并刷新頁(yè)面來(lái)反映購物車(chē)狀態(tài)的變化。Ajax行衛可以在頁(yè)面被載入時(shí)通過(guò)JavaScript添加到頁(yè)面中,只在XMLHttpRequest可用的情況下,為每個(gè)Add to Cart按鈕加上JavaScript處理函數。另一個(gè)方法是在用戶(hù)登錄時(shí)檢測XMLHttpRequest,再決定是提供Ajax版本還是常規基于form提交的版本。
可用性考慮
圍繞著(zhù)Ajax應用的大部分問(wèn)題都是很普通的問(wèn)題。例如,讓用戶(hù)知道他們的輸入已經(jīng)被注冊并處理,是很重要的,因為在XMLHttpRequest處理過(guò)程中并不能提供通常的漏斗旋轉光標。一種方法是將“確認”按扭上的文本替換為“正在更新中…”,以避免用戶(hù)在等待響應時(shí)多次點(diǎn)擊按鈕。
另一個(gè)問(wèn)題是,用戶(hù)可能沒(méi)有注意到他們正在觀(guān)看的頁(yè)面已經(jīng)被更新??梢酝ㄟ^(guò)使用各種視覺(jué)技巧來(lái)將用戶(hù)的眼光吸引到頁(yè)面的更新區域。還有一個(gè)問(wèn)題是通過(guò)Ajax更新頁(yè)面打斷了瀏覽器“退回前頁(yè)”按鈕的正常工作,地址欄中的URL不能反映頁(yè)面的全部狀態(tài),并且不能使用書(shū)簽功能。參見(jiàn)Resource章節中列出的網(wǎng)站地址上的文章來(lái)了解更多Ajax應用關(guān)于可用性方面的問(wèn)題。
服務(wù)器負載
使用Ajax界面代替傳統的基于form的界面可能戲劇性地增加傳遞到服務(wù)器的請求數量。例如,一個(gè)普通的Google搜索給服務(wù)器造成一次命中,并在用戶(hù)確認搜索表單時(shí)發(fā)生。然而,Google Suggest,將會(huì )試圖自動(dòng)完成你的搜索詞,在用戶(hù)打字時(shí)將會(huì )往服務(wù)器發(fā)送多個(gè)請求。在開(kāi)發(fā)一個(gè)Ajax應用時(shí),要注意到你將會(huì )發(fā)送多少請求到用戶(hù)器端,以及服務(wù)器的負載指標。你可以通過(guò)在客戶(hù)端適當地緩存請求、與服務(wù)器響應來(lái)緩減負載壓力。你也應該在設計Ajax應用時(shí)盡量在客戶(hù)端處理更多的邏輯,而不用與服務(wù)器端通訊。
處理異步
一定要記住,沒(méi)有任何東西可以保證XMLHttpRequest將會(huì )按照它們被發(fā)送的順序來(lái)依次結束。實(shí)際上,你在設計系統時(shí),腦子里應該始終假定它們不會(huì )按原來(lái)順序結束。在購物車(chē)例子中,使用了一個(gè)最后更新的時(shí)間戳來(lái)保證最新的數據不會(huì )被改寫(xiě)。這個(gè)非?;镜姆椒梢栽谫徫镘?chē)場(chǎng)景中工作,但可能不能在其它情況下工作。在設計時(shí)刻就要考慮你該如何處理異步服務(wù)器響應。
結論
你現在應該對于Ajax的基本原則有了一個(gè)良好的了解,另外,你應該理解一些更高級的隨Ajax方法而來(lái)的設計問(wèn)題。創(chuàng )建一個(gè)成功的Ajax應用需要一系列的方法—從JavaScript UI設計到服務(wù)器端架構—但是你現在應該已經(jīng)具備了需要使用到的Ajax核心知識。
There‘s good news if you‘re feeling daunted by the complexity of writing a large Ajax application using the techniques demonstrated here. Just as frameworks like Struts, Spring, and Hibernate have evolved to abstract Web application development away from the low-level details of the Servlet API and JDBC, so toolkits are appearing to ease Ajax development. Some of these focus solely on the client side, providing easy ways to add visual effects to your pages or streamlining the use of XMLHttpRequest. Others go further, providing means to automatically generate Ajax interfaces from server-side code. These frameworks do the heavy lifting for you, so that you can take a more high-level approach to Ajax development. I‘ll be looking at some of them in this series.
The Ajax community is fast moving, and there‘s a great deal of valuable information out there. Before reading the next installment in this series, I recommend that you consult the articles listed in the Resources section, especially if you‘re new to Ajax or client-side development. You should also take some time to study the example source code and think about ways to improve it.
In the next article in this series, I‘ll discuss the XMLHttpRequest API in more detail and suggest ways to create XML easily from your JavaBeans. I‘ll also show you alternatives to XML for Ajax data transfer, such as the JSON (JavaScript Object Notation) lightweight data-interchange format.
Download
Sample code j-ajax1.zip 8 KB FTP
Resources
Learn
"Beyond the DOM" (Dethe Elza, developerWorks, May 2005): Useful JavaScript techniques for XML document access.
"Ajax and scripting Web services with E4X" (Paul Fremantle and Anthony Elder, developerWorks, April 2005): Use Ajax to make SOAP calls in browsers that support the E4X JavaScript extension.
"Ajax: A New Approach to Web Applications" (Jesse James Garrett, Adaptive Path, February 2005): The seminal essay that gave Ajax its name.
The Java BluePrints Solutions Catalog: Documents the application of Ajax to several common Web application scenarios.
AjaxPatterns.org: A wiki that includes several UI techniques to improve Ajax applications.
XMLHttpRequest Usability Guidelines: Suggestions for using Ajax to enhance user experience.
Ajax Mistakes: Usability problems that Ajax applications should avoid.
The Java technology zone: Find articles about every aspect of Java programming.
Get products and technologies
Mozilla Firefox: The DOM Inspector and JavaScript Debugger extension take a lot of the pain out of Ajax development.
Discuss
Participate in the discussion forum for this content.
developerWorks blogs: Get involved in the developerWorks community.
About the author
Philip McCarthy is software development consultant specializing in Java and Web technologies. He is currently working on Hewlett Packard‘s Digital Media Platform project at HP Labs, Bristol. In recent years Phil has developed several rich Web clients employing asynchronous server communication and DOM scripting. He is glad we now have a name for them. You can get in touch with Phil at philmccarthy@gmail.com.
聯(lián)系客服