頁面重載提出了一個在Web應用開發中最大的可用性障礙,對於Java開發來說也是一個重大的挑戰。在本文中,作者Philip McCarthy介紹了通過後台通道的方法來創建動態Web應用的經驗。
Ajax(Asynchronous JavaScript and XML)是一個結合了Java技術、XML、以及JavaScript的編程技術,可以讓你構建基於Java技術的Web應用,並打破了使用頁面重載的慣例。
Ajax,異步JavaScript與XML,是使用客戶端腳本與Web服務器交換數據的Web應用開發方法。這樣,Web頁面不用打斷交互流程進行重新加裁,就可以動態地更新。使用Ajax,你可以創建接近本地桌面應用的,直接的、高可用的、更豐富的、更動態的Web用戶接口界面。
Ajax不是一個技術,它更像是一個模式—標志並描述有用的設計技巧的一種方法。對於剛了解它的許多開發人員來說,它是一種新的感覺,但是實現Ajax的所有組件都已存在了許多年。
當前的熱鬧是因為在2004與2005年出現了一些基於Ajax的非常動態的WebUI,尤其是Google的GMail與Maps應用系統、與照片共享網站Flickr。這些UI充分地使用了後台通道,也被一些開發者稱為“Web 2.0”,並導致了大家對Ajax應用興趣的猛漲。
在本系列中,我將給出所有你需要的開發你自己的Ajax應用的工具。在這第一篇文章中,我將解釋在Ajax背後的概念,示范為基於Web的應用系統創建一個Ajax接口的基本步驟。我將使用示例代碼來示范實現Ajax動態接口的服務器端Java代碼與客戶端JavaScript腳本。最後,我將指出一些Ajax方法中易犯的錯誤,以及在創建Ajax應用時應該考慮的廣泛范圍內的可用性與易訪問性方面的問題。
一個更好的購物車 你可以使用Ajax來加強傳統的Web應用,通過消除頁面載入來使交互更流暢。為了示范它,我將使用一個簡單的,能動態更新加入的物品購物車。結合一個在線商店,這個方法可以不用等待點擊後的頁面重載,而讓我們繼續浏覽並挑選物品到購物車中。
雖然,本文中的代碼針對購物車例子,但其中展示的技術可以用到其它的Ajax應用中。列表1中展示了購物車示例所使用的HTML代碼。在整篇文章中,我都將會引用到這些HTML代碼。
Ajax處理過程 一個Ajax交互從一個稱為XMLHttpRequest的JavaScript對象開始。如同名字所暗示的,它允許一個客戶端腳本來執行HTTP請求,並且將會解析一個XML格式的服務器響應。Ajax處理過程中的第一步是創建一個XMLHttpRequest實例。使用HTTP方法(GET或POST)來處理請求,並將目標URL設置到XMLHttpRequest對象上。
現在,記住Ajax如何首先處於異步處理狀態?當你發送HTTP請求,你不希望浏覽器掛起並等待服務器的響應,取而代之的是,你希望通過頁面繼續響應用戶的界面交互,並在服務器響應真正到達後處理它們。
要完成它,你可以向XMLHttpRequest注冊一個回調函數,並異步地派發XMLHttpRequest請求。控制權馬上就被返回到浏覽器,當服務器響應到達時,回調函數將會被調用。
在Java Web服務器上,到達的請求與任何其它HttpServletRequest一樣。在解析請求參數後,servlet執行必需的應用邏輯,將響應序列化到XML中,並將它寫回HttpServletResponse。
回到客戶端,注冊在XMLHttpRequest上的回調函數現在會被調用來處理由服務器返回的XML文檔。最後,通過更新用戶界面來響應服務器傳輸過來數據,使用JavaScript來操縱頁面的HTML DOM。圖1是Ajax處理過程的一個時序圖。
圖1:Ajax處理過程 現在,你應該對Ajax處理過程有了一個高層視圖。我將進入其中的每一步看看更細節的內容。如果你找不到自己的位置時,就回頭再看看圖1,加—因為Ajax方法的異步本質,所以時序圖並不是筆直向前的。
發送一個XMLHttpRequest 我將從Ajax時序圖的起點開始:從浏覽器創建並發送一個XMLHttpRequest。不幸的是,在不同的浏覽器中創建XMLHttpRequest的方法都不一樣。列表2中示例的JavaScript函數消除了這些與浏覽器種類相關的問題,正確檢測與當前浏覽器相關的方法,並返回一個可以使用的XMLHttpRequest。最好將它看成備用代碼,將它簡單拷貝到你的JavaScript庫中,在需要一個XMLHttpRequest時使用它即可。
列表2:跨浏覽器創建一個XMLHttpRequest
/*
* 返回一個新建的XMLHttpRequest對象,
若浏覽器不支持則失敗
*/
function newXMLHttpRequest()
{
var xmlreq = false;
if (window.XMLHttpRequest)
{
// 在非Microsoft浏覽器中
創建XMLHttpRequest對象
xmlreq = new XMLHttpRequest();
} else if (window.ActiveXObject)
{
//通過MS ActiveX創建XMLHttpRequest
try {
// 嘗試按新版InternetExplorer方法創建
xmlreq = new ActiveXObject
("Msxml2.XMLHTTP");
} catch (e1) {
// 創建請求的ActiveX對象失敗
try {
// 嘗試按老版InternetExplorer方法創建
xmlreq = new ActiveXObject
("Microsoft.XMLHTTP");
} catch (e2) {
// 不能通過ActiveX創建XMLHttpRequest
}
}
}
return xmlreq;
}
稍後,我將討論如何對待不支持XM