面向Java程序員的Ajax:構建動態Java程序 – JAVA編程語言程序開發技術文章

Ajax(即異步 JavaScript 和 XML)是一種 Web 應用程序開發的手段,它采用客戶端腳本與 Web 服務器交換數據。所以,不必采用會中斷交互的完整頁面刷新,就可以動態地更新 Web 頁面。使用 Ajax,可以創建更加豐富、更加動態的 Web 應用程序用戶界面,其即時性與可用性甚至能夠接近本機桌面應用程序。

  Ajax 不是一項技術,而更像是一個 模式 —— 一種識別和描述有用的設計技術的方式。Ajax 是新穎的,因為許多開發人員才剛剛開始知道它,但是所有實現 Ajax 應用程序的組件都已經存在若幹年瞭。它目前受到重視是因為在 2004 和 2005 年出現瞭一些基於 Ajax 技術的非常棒的動態 Web UI,最著名的就是 Google 的 GMail 和 Maps 應用程序,以及照片共享站點 Flickr。這些用戶界面具有足夠的開創性,有些開發人員稱之為“Web 2.0”,因此對 Ajax 應用程序的興趣飛速上升。

  在這個系列中,我將提供使用 Ajax 開發應用程序需要的全部工具 。在第一篇文章中,我將解釋 Ajax 背後的概念,演示為基於 Java 的 Web 應用程序創建 Ajax 界面的基本步驟。我將使用代碼示例演示讓 Ajax 應用程序如此動態的服務器端 Java 代碼和客戶端 JavaScript。最後,我將指出 Ajax 方式的一些不足,以及在創建 Ajax 應用程序時應當考慮的一些更廣的可用性和訪問性問題。

  更好的購物車

  可以用 Ajax 增強傳統的 Web 應用程序,通過消除頁面裝入從而簡化交互。為瞭演示這一點,我采用一個簡單的購物車示例,在向裡面添加項目時,它會動態更新。這項技術如果整合到在線商店,那麼用戶可以持續地瀏覽和向購物車中添加項目,而不必在每次點擊之後都等候完整的頁面更新。雖然這篇文章中的有些代碼特定於購物車示例,但是演示的技術可以應用於任何 Ajax 應用程序。清單 1 顯示瞭購物車示例使用的有關 HTML 代碼,整篇文章中都會使用這個 HTML。

  清單1. 購物車示例的有關片斷

<!– Table of products from stores 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 對象。顧名思義,它允許客戶端腳本執行 HTTP 請求,並解析 XML 服務器響應。Ajax 往返過程的第一步是創建 XMLHttpRequest 的實例。在 XMLHttpRequest 對象上設置請求使用的 HTTP 方法(GET 或 POST)以及目標 URL。

  現在,您還記得 Ajax 的第一個 a 是代表 異步(asynchronous) 嗎?在發送 HTTP 請求時,不想讓瀏覽器掛著等候服務器響應。相反,您想讓瀏覽器繼續對用戶與頁面的交互進行響應,並在服務器響應到達時再進行處理。為瞭實現這個要求,可以在 XMLHttpRequest 上註冊一個回調函數,然後異步地分派 XMLHttpRequest。然後控制就會返回瀏覽器,當服務器響應到達時,會調用回調函數。

  在 Java Web 服務器上,請求同其他 HttpServletRequest 一樣到達。在解析瞭請求參數之後,servlet 調用必要的應用程序邏輯,把響應序列化成 XML,並把 XML 寫入 HttpServletResponse。

  回到客戶端時,現在調用註冊在 XMLHttpRequest 上的回調函數,處理服務器返回的 XML 文檔。最後,根據服務器返回的數據,用 JavaScript 操縱頁面的 HTML DOM,把用戶界面更新。圖 1 是 Ajax 往返過程的順序圖。

 Ajax 往返過程的順序圖
圖 1. Ajax 往返過程
  現在您對 Ajax 往返過程有瞭一個高層面的認識。下面我將放大其中的每一步驟,進行更詳細的觀察。如果過程中迷瞭路,請回頭看圖 1 —— 由於 Ajax 方式的異步性質,所以順序並非十分簡單。

 分派 XMLHttpRequest

  我將從 Ajax 序列的起點開始:創建和分派來自瀏覽器的 XMLHttpRequest。不幸的是,不同的瀏覽器創建 XMLHttpRequest 的方法各不相同。清單 2 的 JavaScript 函數消除瞭這些依賴於瀏覽器的技巧,它可以檢測當前瀏覽器要使用的正確方式,並返回一個可以使用的 XMLHttpRequest。最好是把它當作輔助代碼:隻要把它拷貝到 JavaScript 庫,並在需要 XMLHttpRequest 的時候使用它就可以瞭。

  清單 2. 創建跨瀏覽器的 XMLHttpRequest

/*
* Returns a new XMLHttpRequest object, or false if this browser
* doesnt support it
*/
function newXMLHttpRequest() {

 var xmlreq = false;

 if (window.XMLHttpRequest) {

  // Create XMLHttpRequest object in non-Microsoft browsers
  xmlreq = new XMLHttpRequest();

 } else if (window.ActiveXObject) {

  // Create XMLHttpRequest via MS ActiveX
  try {
   // Try to create XMLHttpRequest in later versions
   // of Internet Explorer

   xmlreq = new ActiveXObject(“Msxml2.XMLHTTP”);

  } catch (e1) {

   // Failed to create required ActiveXObject

   try {
    // Try version supported by older versions
    // of Internet Explorer
    xmlreq = new ActiveXObject(“Microsoft.XMLHTTP”);
   } catch (e2) {
    // Unable to create an XMLHttpRequest with ActiveX
   }
  }
 }
 return xmlreq;
}

  稍後我將討論處理那些不支持 XMLHttpRequest 的瀏覽器的技術。目前,示例假設清單 2 的 newXMLHttpRequest 函數總能返回 XMLHttpRequest 實例。

  返回示例的購物車場景,我想要當用戶在目錄項目上點擊 Add to Cart 時啟動 Ajax 交互。名為 addToCart() 的 onclick 處理函數負責通過 Ajax 調用來更新購物車的狀態(請參閱 清單 1)。正如清單 3 所示,addToCart() 需要做的第一件事是通過調用清單 2 的 newXMLHttpRequest() 函數得到 XMLHttpRequest 對象。接下來,它註冊一個回調函數,用來接收服務器響應(我稍後再詳細解釋這一步;請參閱 清單 6)。 因為請求會修改服務器上的狀態,所以我將用 HTTP POST 做這個工作。通過 POST 發送數據要求三個步驟。第一,需要打開與要通信的服務器資源的 POST 連接 —— 在這個示例中,服務器資源是一個映射到 URL cart.do 的 servlet。然後,我在 XMLHttpRequest 上設置一個頭,指明請求的內容是表單 編碼的數據。最後,我用表單編碼的數據作為請求體發送請求。

  清單 3 把這些步驟放在瞭一起。

  清單 3. 分派 Add to Cart XMLHttpRequest

/*
* Adds an item, identified by its product code, to the shopping cart
* itemCode – product code of the item to add.
*/
function addToCart(itemCode) {

 // Obtain an XMLHttpRequest instance
 var req = newXMLHttpRequest();

 // Set the handler function to receive callback notifications
 // from the request object
 var handlerFunction = getReadyStateHandler(req, updateCart);
 req.onreadystatechange = handlerFunction;

 // Open an HTTP POST connection to the shopping cart servlet.
 // Third parameter specifies request is asynchronous.
 req.open(“POST”, “cart.do”, true);

 // Specify that the body of the request contains form data
 req.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);

 // Send form encoded data stating that I want to add the
 // specified item to the cart.
 req.send(“action=add&item=”+itemCode);
}

  這就是建立 Ajax 往返過程的第一部分,即創建和分派來自客戶機的 HTTP 請求。接下來是用來處理請求的 Java servlet 代碼。 
  servlet 請求處理

  用 servlet 處理 XMLHttpRequest,與處理普通的瀏覽器 HTTP 請求一樣。可以用 HttpServletRequest.getParameter() 得到在 POST 請求體中發送的表單編碼數據。Ajax 請求被放進與來自應用程序的常規 Web 請求一樣的 HttpSession 中。對於示例購物車場景來說,這很有用,因為這讓我可以把購物車狀態封裝在 JavaBean 中,並在請求之間在會話中維持這個狀態。

  清單 4 是處理 Ajax 請求、更新購物車的簡單 servlet 的一部分。Cart bean 是從用戶會話中獲得的,並根據請求參數更新它的狀態。然後 Cart 被序列化成 XML,XML 又被寫入 ServletResponse。重要的是把響應的內容類型設置為 application/xml,否則 XMLHttpRequest 不會把響應內容解析成 XML DOM。

  清單 4. 處理 Ajax 請求的 servlet 代碼

public void doPost(HttpServl

發佈留言