本人僅出于學(xué)習(xí)目的翻譯,完整無誤文章請參見原文,! 面向Java開發(fā)者的Ajax:構(gòu)建動態(tài)的Java應(yīng)用程序 Ajax鋪設(shè)了更好的開發(fā)Web應(yīng)用的道路 級別:中級 Philip McCarthy (mailto:[email protected]?subject=Build dynamic Java applications), Software Development Consultant, Independent Consultant 9月20日2005年 頁面重載提出了一個在Web應(yīng)用開發(fā)中最大的可用性障礙,,對于java開發(fā)來說也是一個重大的挑戰(zhàn)。在本系列中,,作者Philip McCarthy介紹了通過后臺通道的方法來創(chuàng)建動態(tài)Web應(yīng)用的經(jīng)驗,。Ajax(Asynchronous JavaScript and XML)是一個結(jié)合了Java技術(shù)、XML,、以及JavaScript的編程技術(shù),,可以讓你構(gòu)建基于Java技術(shù)的Web應(yīng)用,并打破了使用頁面重載的慣例,。 Ajax,,異步JavaScript與XML,是使用客戶端腳本與Web服務(wù)器交換數(shù)據(jù)的Web應(yīng)用開發(fā)方法,。這樣,,Web頁面不用打斷交互流程進行重新加裁,就可以動態(tài)地更新。使用Ajax,,你可以創(chuàng)建接近本地桌面應(yīng)用的,,直接的、高可用的,、更豐富的,、更動態(tài)的Web用戶接口界面。 Ajax不是一個技術(shù),,它更像是一個模式—標(biāo)志并描述有用的設(shè)計技巧的一種方法,。對于剛了解它的許多開發(fā)人員來說,它是一種新的感覺,,但是實現(xiàn)Ajax的所有組件都已存在了許多年,。當(dāng)前的熱鬧是因為在2004與2005年出現(xiàn)了一些基于Ajax的非常動態(tài)的WebUI,尤其是Google的GMail與Maps應(yīng)用系統(tǒng),、與照片共享網(wǎng)站Flickr,。這些UI充分地使用了后臺通道,也被一些開發(fā)者稱為“Web 2.0”,,并導(dǎo)致了大家對Ajax應(yīng)用興趣的猛漲,。 在本系列中,我將給出所有你需要的開發(fā)你自己的Ajax應(yīng)用的工具,。在這第一篇文章中,,我將解釋在Ajax背后的概念,示范為基于Web的應(yīng)用系統(tǒng)創(chuàng)建一個Ajax接口的基本步驟,。我將使用示例代碼來示范實現(xiàn)Ajax動態(tài)接口的服務(wù)器端Java代碼與客戶端JavaScript腳本,。最后,我將指出一些Ajax方法中易犯的錯誤,,以及在創(chuàng)建Ajax應(yīng)用時應(yīng)該考慮的廣泛范圍內(nèi)的可用性與易訪問性方面的問題,。 一個更好的購物車 你可以使用Ajax來加強傳統(tǒng)的Web應(yīng)用,通過消除頁面載入來使交互更流暢,。為了示范它,,我將使用一個簡單的,能動態(tài)更新加入的物品購物車,。結(jié)合一個在線商店,,這個方法可以不用等待點擊后的頁面重載,而讓我們繼續(xù)瀏覽并挑選物品到購物車中,。雖然,,本文中的代碼針對購物車?yán)樱渲姓故镜募夹g(shù)可以用到其它的Ajax應(yīng)用中,。列表1中展示了購物車示例所使用的HTML代碼,。在整篇文章中,,我都將會引用到這些HTML代碼。 列表1:購物車示例的相關(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處理過程 一個Ajax交互從一個稱為XMLHttpRequest的JavaScript對象開始,。如同名字所暗示的,,它允許一個客戶端腳本來執(zhí)行HTTP請求,并且將會解析一個XML格式的服務(wù)器響應(yīng),。Ajax處理過程中的第一步是創(chuàng)建一個XMLHttpRequest實例,。使用HTTP方法(GET或POST)來處理請求,并將目標(biāo)URL設(shè)置到XMLHttpRequest對象上,。 現(xiàn)在,,記住Ajax如何首先處于異步處理狀態(tài)?當(dāng)你發(fā)送HTTP請求,,你不希望瀏覽器掛起并等待服務(wù)器的響應(yīng),取而代之的是,,你希望通過頁面繼續(xù)響應(yīng)用戶的界面交互,,并在服務(wù)器響應(yīng)真正到達后處理它們。要完成它,,你可以向XMLHttpRequest注冊一個回調(diào)函數(shù),,并異步地派發(fā)XMLHttpRequest請求??刂茩?quán)馬上就被返回到瀏覽器,,當(dāng)服務(wù)器響應(yīng)到達時,回調(diào)函數(shù)將會被調(diào)用,。 在Java Web服務(wù)器上,,到達的請求與任何其它HttpServletRequest一樣。在解析請求參數(shù)后,,servlet執(zhí)行必需的應(yīng)用邏輯,,將響應(yīng)序列化到XML中,并將它寫回HttpServletResponse,。 回到客戶端,注冊在XMLHttpRequest上的回調(diào)函數(shù)現(xiàn)在會被調(diào)用來處理由服務(wù)器返回的XML文檔,。最后,,通過更新用戶界面來響應(yīng)服務(wù)器傳輸過來數(shù)據(jù),使用JavaScript來操縱頁面的HTML DOM,。圖1是Ajax處理過程的一個時序圖,。 圖1:Ajax處理過程
現(xiàn)在,你應(yīng)該對Ajax處理過程有了一個高層視圖,。我將進入其中的每一步看看更細(xì)節(jié)的內(nèi)容,。如果你找不到自己的位置時,就回頭再看看圖1,加—因為Ajax方法的異步本質(zhì),,所以時序圖并不是筆直向前的,。
發(fā)送一個XMLHttpRequest 我將從Ajax時序圖的起點開始:從瀏覽器創(chuàng)建并發(fā)送一個XMLHttpRequest。不幸的是,,在不同的瀏覽器中創(chuàng)建XMLHttpRequest的方法都不一樣,。列表2中示例的JavaScript函數(shù)消除了這些與瀏覽器種類相關(guān)的問題,正確檢測與當(dāng)前瀏覽器相關(guān)的方法,,并返回一個可以使用的XMLHttpRequest,。最好將它看成備用代碼,將它簡單拷貝到你的JavaScript庫中,,在需要一個XMLHttpRequest時使用它即可,。 列表2:跨瀏覽器創(chuàng)建一個XMLHttpRequest /* * 返回一個新建的XMLHttpRequest對象,若瀏覽器不支持則失敗 */ function newXMLHttpRequest() { var xmlreq = false; if (window.XMLHttpRequest) { // 在非Microsoft瀏覽器中創(chuàng)建XMLHttpRequest對象 xmlreq = new XMLHttpRequest(); } else if (window.ActiveXObject) { //通過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) { // 不能通過ActiveX創(chuàng)建XMLHttpRequest } } } return xmlreq; } 稍后,,我將討論如何對待不支持XMLHttpReauest的瀏覽器的一些技巧?,F(xiàn)在,列表2中展示的示例函數(shù)將總是可以返回一個XMLHttpReauest實例,。 回到購物車?yán)拥膱鼍爸?,只要用戶針對某一個目錄條目點擊了Add to Cart按鈕,我就要調(diào)用一個Ajax交互,。名為addToCart()的onclick函數(shù)通過Ajax調(diào)用(如列表1中所示)來負(fù)責(zé)更新購物車的狀態(tài),。在列表3中,addToCart()要做的第一件事就是通過調(diào)用newXMLHttpReauest函數(shù)(如列表2中所示)來獲取一個XMLHttpRequest的實例,,并且注冊一個回調(diào)函數(shù)來接受服務(wù)器響應(yīng)(我將在稍后詳細(xì)解釋,,請參見列表6)。 因為,,此請求將會修改服務(wù)器狀態(tài),,我將使用一個HTTP POST來處理它。通過POST傳送數(shù)據(jù)需要三個步驟:首先,,我需要打開一個到進行通訊的服務(wù)器資源的POST連接—在現(xiàn)在例子中是一個URL映射為cart.do的服務(wù)器端servlet,。下一步,設(shè)置XMLHttpRequest的頭信息,,以標(biāo)志請求的內(nèi)容為form-encoded,。最后,將form-encoded數(shù)據(jù)作為請求體,,并發(fā)送此請求,。 列表3中集中展示了這些步驟。 列表3:發(fā)送一個添加到購物車XMLHttpRequest /* * 通過產(chǎn)品編碼,,在購物車中添加一個條目 * itemCode – 需要添加條目的產(chǎn)品編碼 */ function addToCart(itemCode) { // 獲取一個XMLHttpRequest實例 var req = newXMLHttpRequest(); // 設(shè)置用來從請求對象接收回調(diào)通知的句柄函數(shù) var handlerFunction = getReadyStateHandler(req, updateCart); req.onreadystatechange = handlerFunction;
// 打開一個聯(lián)接到購物車servlet的HTTP POST聯(lián)接 // 第三個參數(shù)表示請求是異步的 req.open("POST", "cart.do", true);
// 指示請求體包含form數(shù)據(jù) req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 發(fā)送標(biāo)志需要添加到購物車中條目的form-encoded數(shù)據(jù) req.send("action=add&item="+itemCode); } 結(jié)合以上內(nèi)容,,你可以了解到Ajax處理過程的第一部分—就是在客戶端創(chuàng)建并發(fā)送HTTP請求,。下一步是用來處理請求的Java Servlet代碼。
Servlet請求處理 通過一個servlet來處理XMLHttpRequest與處理一個來自瀏覽器的普通的HTTP請求基本上相似,??梢酝ㄟ^調(diào)用HttpServletRequest.getParameter()來獲取由POST請求體傳送過來的form-encoded數(shù)據(jù)。Ajax請求也與普通的WEB請求樣都成為此應(yīng)用同一HttpSession會話進程的一部分,。這對于購物車?yán)觼碚f很有肜,,因為我們可以通過會話將多個請求的狀態(tài)都保存到同一個JavaBean購物車對象中,并可以序列化,。 列表4是處理Ajax請求并更新購物車的簡單servlet的代碼片斷,。從用戶會話中檢索出一個Cart Bean,并按請求的參數(shù)更新它,。之后Cart Bean被序列化到XML,,并被寫回ServletRespone。注意,,一定要將響應(yīng)內(nèi)容的類型設(shè)置為application/xml,,否則,XMLHttpRequest將不能將響應(yīng)內(nèi)容解析為一個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)) { // 在購物車中添加或移除一個條目 if ("add".equals(action)) { cart.addItem(item); } else if ("remove".equals(action)) { cart.removeItems(item); } } // 將購物車狀態(tài)序列化到XML String cartXml = cart.toXml();
// 將XML寫入response. res.setContentType("application/xml"); res.getWriter().write(cartXml); } 列表5展示了由Cart.toXml()方法生成的XML。注意到生成的cart元素的屬性,,是一個通過System.currentTimeMillis()生成的時間戳,。 列表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> 如果你觀察一下下載站點提供的例子應(yīng)用源碼中的Cart.java,你將會看到它通過簡單地追加字符串來生成XML,。對于本例子來說,,它已經(jīng)足夠了,我將會在本系統(tǒng)文章的以后一期中介紹一些更好的方法,。 現(xiàn)在你知道了CartServlet如何響應(yīng)一個XMLHttpRequest,。下一步是返回到客戶端,如何用服務(wù)器響應(yīng)來更新頁面狀態(tài),。
通過JavaScript來處理服務(wù)器響應(yīng) XMLHttpRequest的readyState屬性是一個給出請求生命周期狀態(tài)的數(shù)字值,。它從表示“未初始化”的0變化到表示“完成”的4。每次readyState改變時,,都會引發(fā)readystatechange事件,,通過onreadystatechange屬性配置回調(diào)處理函數(shù)將會被調(diào)用。 在列表3中,,你已看到通過調(diào)用函數(shù)getReadyStateHandler()創(chuàng)建了一個處理函數(shù),,并被配置給onreadystatechange屬性。getReadyStateHandler()使用了這樣的事實:函數(shù)是JavaScript中的主要對象,。這意味著,,函數(shù)可以作為參數(shù)被傳遞到其它函數(shù),,并且可以創(chuàng)建并返回其它函數(shù)。getReadystateHandler()要做是就是返回一個函數(shù),,來檢查XMLHttpRequet是否已經(jīng)完成處理,,并傳遞XML服務(wù)器響應(yīng)到由調(diào)用者指定的處理函數(shù)。列表6是getReadyStateHandler()的代碼,。 列表6:函數(shù)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) { // 返回一個監(jiān)聽XMLHttpRequest實例的匿名函數(shù) return function () { // 如果請求的狀態(tài)是“完成” if (req.readyState == 4) { // 檢查是否成功接收了服務(wù)器響應(yīng) if (req.status == 200) { // 將載有響應(yīng)信息的XML傳遞到處理函數(shù) responseXmlHandler(req.responseXML); } else { // 有HTTP問題發(fā)生 alert("HTTP error: "+req.status); } } } }
HTTP狀態(tài)碼
在列表6中,,XMLHttpRequest的status屬性被測試用來確定請求是否成功完成。當(dāng)處理簡單的GET與POST請求,,你可以認(rèn)為只要不是200(OK)的狀態(tài)就表示發(fā)生了錯誤,。若服務(wù)器發(fā)送了一個重定向響應(yīng)(例如,301或302),,瀏覽器會透明地完成重定向并從新位置獲取相應(yīng)的資源,;XMLHttpRequest不會看到重定向狀態(tài)碼。同時,,瀏覽器自動添加一個緩存控制:對于所有XMLHttpRequest都使用no-cache header,,這樣客戶端代碼就可以不用處理304(not-modified)響應(yīng)。
關(guān)于getReadyStateHandler() getReadyStateHandler()是相對比較復(fù)雜的一段代碼,,特別當(dāng)你不能熟悉閱讀JavaScript時,。折中方案是在你的JavaScript庫中包含此函數(shù),你可以簡單地處理Ajax服務(wù)器響應(yīng),,而不用去注意XMLHttpRequest的內(nèi)部細(xì)節(jié),。重要是你自己要理解在代碼中如何使用getReadyStateHandler()。 在列表3中,,你看到getReadyStateHandler()被這樣調(diào)用: handlerFunction=getReadyStateHandler(req,updateCart),。 由它返回的函數(shù)將會檢查在req變量中的XMLHttpRequest是否已完成,并調(diào)用由updateCart指定的回調(diào)方法處理響應(yīng)XML,。
提取購物車數(shù)據(jù) 列表7中展示了updateCart()中的代碼,。此函數(shù)使用DOM來解析購物車XML文檔,并更新WEB頁面(參見列表1)來反映新的購物車內(nèi)容,。注意對用來提取數(shù)據(jù)的XML DOM的調(diào)用,。Cart元素上生成的屬性,即序列化時生成的時間戳,,通過檢測它可以保證不會用老的數(shù)據(jù)來覆蓋新的購物車數(shù)據(jù),。Ajax請求天生就是異步的,通過這個檢測可以有效避免在過程外到達的服務(wù)器響應(yīng)的干擾,。 列表7:更新頁面來反映出購物車XML文檔內(nèi)容 function updateCart(cartXML) { // 從文檔中獲取根元素“cart” var cart = cartXML.getElementsByTagName("cart")[0]; // 保證此文檔是最新的 var generated = cart.getAttribute("generated"); if (generated > lastCartUpdate) { lastCartUpdate = generated;
// 清除HTML列表,,用來顯示購物車內(nèi)容 var contents = document.getElementById("cart-contents"); contents.innerHTML = "";
// 在購物車內(nèi)按條目循環(huán) var items = cart.getElementsByTagName("item"); for (var I = 0 ; I < items.length ; I++) { var item = items[I]; // 從name與quantity元素中提取文本節(jié)點 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); } } // 更新購物車的金額累計 document.getElementById("total").innerHTML = cart.getAttribute("total"); } 到現(xiàn)在,關(guān)于Ajax處理過程的教程已經(jīng)結(jié)束,,也許你想讓應(yīng)用運行起來,,并看看它的實際運作(參見下載部分),。這個例子非常簡單,有非常大的改進的余地,。比如,,我在服務(wù)器端代碼中包含了從購物車中移除條目的代碼,但從客戶端UI中沒有訪問的途徑,。作為一個練習(xí),,嘗試在現(xiàn)有的JavaScript基礎(chǔ)上實際這個功能。
使用Ajax的挑戰(zhàn) 與任何技術(shù)一樣,,使用Ajax在相當(dāng)多的方面都可能范錯誤,。我在這兒討論的問題目前都缺少解決方案,并將會隨著Ajax的成熟而解決或提高,。隨著開發(fā)Ajax應(yīng)用經(jīng)驗的不斷獲取,,開發(fā)者社區(qū)中將會出現(xiàn)最好的實踐經(jīng)驗與指導(dǎo)方針。 XMLHttpRequest的有效性 Ajax開發(fā)者面對的一個最大問題是當(dāng)XMLHttpRequest不可用時如何反應(yīng),。雖然大部分現(xiàn)代瀏覽器支持XMLHttpRequest,,但還是有少量的用戶,他們的瀏覽器不能支持,,或由于瀏覽器安全設(shè)置而阻止對XMLHttpRequest的使用,。若你的Web應(yīng)用發(fā)布于公司內(nèi)部的Intranet上,你很可能可以指定支持哪種瀏覽器,,并可以確保XMLHttpRequest是可用的,。若你在公共WEB上發(fā)布,則你必須意識到由于假定XMLHttpRequest是可用的,,所有就阻止了老瀏覽器,、手持設(shè)備瀏覽器等等用戶來使用你的系統(tǒng),。 然而,,你應(yīng)該盡力保證應(yīng)用系統(tǒng)“正常降級”使用,在系統(tǒng)中保留適用于不支持XMLHttpRequest的瀏覽器的功能,。在購物車?yán)又?,最好的方法是有一個Add to Cart按鈕,可以進行常規(guī)的提交處理,,并刷新頁面來反映購物車狀態(tài)的變化,。Ajax行衛(wèi)可以在頁面被載入時通過JavaScript添加到頁面中,只在XMLHttpRequest可用的情況下,,為每個Add to Cart按鈕加上JavaScript處理函數(shù),。另一個方法是在用戶登錄時檢測XMLHttpRequest,再決定是提供Ajax版本還是常規(guī)基于form提交的版本,。 可用性考慮 圍繞著Ajax應(yīng)用的大部分問題都是很普通的問題,。例如,,讓用戶知道他們的輸入已經(jīng)被注冊并處理,是很重要的,,因為在XMLHttpRequest處理過程中并不能提供通常的漏斗旋轉(zhuǎn)光標(biāo),。一種方法是將“確認(rèn)”按扭上的文本替換為“正在更新中…”,以避免用戶在等待響應(yīng)時多次點擊按鈕,。 另一個問題是,,用戶可能沒有注意到他們正在觀看的頁面已經(jīng)被更新??梢酝ㄟ^使用各種視覺技巧來將用戶的眼光吸引到頁面的更新區(qū)域,。還有一個問題是通過Ajax更新頁面打斷了瀏覽器“退回前頁”按鈕的正常工作,地址欄中的URL不能反映頁面的全部狀態(tài),,并且不能使用書簽功能,。參見Resource章節(jié)中列出的網(wǎng)站地址上的文章來了解更多Ajax應(yīng)用關(guān)于可用性方面的問題。 服務(wù)器負(fù)載 使用Ajax界面代替?zhèn)鹘y(tǒng)的基于form的界面可能戲劇性地增加傳遞到服務(wù)器的請求數(shù)量,。例如,,一個普通的Google搜索給服務(wù)器造成一次命中,并在用戶確認(rèn)搜索表單時發(fā)生,。然而,,Google Suggest,將會試圖自動完成你的搜索詞,,在用戶打字時將會往服務(wù)器發(fā)送多個請求,。在開發(fā)一個Ajax應(yīng)用時,要注意到你將會發(fā)送多少請求到用戶器端,,以及服務(wù)器的負(fù)載指標(biāo),。你可以通過在客戶端適當(dāng)?shù)鼐彺嬲埱蟆⑴c服務(wù)器響應(yīng)來緩減負(fù)載壓力,。你也應(yīng)該在設(shè)計Ajax應(yīng)用時盡量在客戶端處理更多的邏輯,,而不用與服務(wù)器端通訊。 處理異步 一定要記住,,沒有任何東西可以保證XMLHttpRequest將會按照它們被發(fā)送的順序來依次結(jié)束,。實際上,你在設(shè)計系統(tǒng)時,,腦子里應(yīng)該始終假定它們不會按原來順序結(jié)束,。在購物車?yán)又校褂昧艘粋€最后更新的時間戳來保證最新的數(shù)據(jù)不會被改寫,。這個非?;镜姆椒梢栽谫徫镘噲鼍爸泄ぷ鳎赡懿荒茉谄渌闆r下工作,。在設(shè)計時刻就要考慮你該如何處理異步服務(wù)器響應(yīng),。 結(jié)論 你現(xiàn)在應(yīng)該對于Ajax的基本原則有了一個良好的了解,,另外,你應(yīng)該理解一些更高級的隨Ajax方法而來的設(shè)計問題,。創(chuàng)建一個成功的Ajax應(yīng)用需要一系列的方法—從JavaScript UI設(shè)計到服務(wù)器端架構(gòu)—但是你現(xiàn)在應(yīng)該已經(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 [email protected].
|
|