時下,大多數 Java 開發人員都很看好 mashup,所以您可能會困惑:Seam 與號稱 Web 2.0 的技術,尤其是 AJax,如何能集成。若能使用 Seam 啟動 JSF 中的部分頁面更新或者用 Google Map 協助 JSF 應用程序 mashup,那將非常酷,不是麼?您不僅能這麼做,而且還非常容易。
我將為您展示如何使用 Seam Remoting API和Ajax4jsf 組件來協助基於 JSF 應用程序中的 Ajax 風格的交互。正如您將會看到的,結合 Seam 和 AJax 的最大好處在於它讓您可以享用所有 Web 2.0 的奢侈東西,而同時又不需要陷於使用 JavaScript XMLHttpRequest 對象的痛苦之中。借助 Seam Remoting 和 AJax4JSf,可以與服務器上的受管 bean 通信,就好像這些 bean 與浏覽器同在本地一樣。浏覽器和服務器狀態保持同步,而且永遠無需處理促成它們之間通信的低層 API。
我首先會為您展示 Seam 是如何推動 Ajax 編程的基於組件的新方式的。您將學會如何使用 Seam Remoting API 來通過 AJax 進行 JavaScript 和服務器端對象間的通信。一旦理解了這種面向 AJax 的新(且簡單的)方式,您就可以使用它來增強 Open 18 應用程序,方法如下:
◆在 Open 18 球場目錄和 Google Maps 之間創建一個 mashup。
◆使用 AJax4JSf 合並應用程序的球場目錄頁和球場細節頁。
◆重新訪問應用程序的 Spring 集成並讓 Spring bean 在 Seam Remoting 的生命周期可用。
Open 18 和 Google Maps 之間的 mashup 讓用戶可以定位地圖中的高爾夫球場目錄中的位置。將此球場目錄和球場細節頁合並起來(並將低層代碼 AJax 化)可以讓您顯示球場的細節信息而無需加載新頁。將 Spring bean 和 Seam Remoting 相集成讓您可以捕獲 Google Maps 位置標記的重定位並能將相關球場的經度和緯度存儲到數據庫中。如您所見,結果就是會產生所有高爾夫球員都喜歡使用的 Web 2.0 風格的應用程序,這真是讓人印象深刻!
如果您曾經深受涉及到大量 JavaScript 的過於復雜的 Ajax 編程之苦,如果到目前為止,您都由於不想面對其復雜性而一直盡量避免使用 Ajax,那麼本文所要教授的內容將會幫助您免除這種擔心。在重構應用程序時,您需要進行一些 Javascript 編碼,但與大多數 AJax 實現不同,Javascript 並不會占據您代碼中的大部分;相反,它只擴展了服務器端的 Java 對象。
通向 AJax 的不同之路
正如在應用程序中希望避免顯式的內存管理一樣,您亦不 希望必須要處理低層的 AJax 請求協議。這麼做只會帶來更大的麻煩(更確切地說,是更多的麻煩),比如多浏覽器支持、數據封送處理、並發沖突、服務器負載以及定制 servlet 和 servlet 過濾器。其中您想要避免的最大的麻煩是無意間公開的無狀態的請求-響應范例,但該范例是基於組件的框架,比如 JSF,所想要隱藏的。
JSF 生命周期通過對底層的 servlet 模型屏蔽應用程序代碼促進了面向組件的設計。為了保持處理 Ajax 的這種抽象性,您可以將低層的這些瑣碎工作交由 Seam Remoting 或 Ajax4JSf 處理。這兩個庫均可負責通過 AJax 交互將 JSF 組件熔合到浏覽器時所需的管道處理。圖 1 顯示了實際應用中的 Seam Remoting。當事件觸發時,比如用戶單擊了一個按鈕,消息就會異步發送給服務器上的組件。一旦收到響應,它就會用來對此頁進行增量更新。用來處理浏覽器和服務器端組件間的交互的低層通信協議都藏於 API 之後。
圖 1. Seam Remoting 熔合 JSF 組件和浏覽器
在圖 1 所示的用例中,用戶能看到單擊按鈕後所發生的方法調用的結果。在研究此用例時,有兩個要點需要注意:
◆該頁永遠無法刷新;
◆客戶端代碼與組件上的方法進行透明通信,而不是顯式地構建然後再請求 URL。標准的 HTTP 請求在後台使用,但客戶端代碼永遠無需直接與 HTTP 協議交互。
Seam Remoting和AJax4JSf
Seam Remoting和Ajax4jsf 是兩個獨特的庫,可分別服務於 JSF 的 “Ajax 化” 的目的。兩個庫均使用 Ajax 來引入交互模型,其中浏覽器和服務器間的通信可以在後台異步發生,並對用戶不可見。沒有必要為了執行服務器上的方法而浪費用戶頁面重載的時間。在這些庫所發出的 Ajax 請求中由服務器檢索到的信息可用來增量地 “實時” 更新頁面的狀態。兩個庫均可配備生命周期,此生命周期可以在浏覽器需要的時候恢復(restore)組件的狀態。這種 AJax 交互並不是真的請求而是一種 “恢復並執行”。浏覽器像是 “敲敲” 服務器的 “肩膀”,請它在服務器端的一個受管 bean 上執行一個方法並返回結果。
雖然這兩個庫工作起來有些差別,但它們並不是相互排斥的。由於它們都采用的是 JSF 組件模型,所以二者可以很容易地相互結合,這將在本文後面的部分詳細介紹。目前,我們只需分別考慮二者各自將 AJax 風格的交互引入 JSF 應用程序的方式:
Seam Remoting 提供了 Javascript API,可以使用這些 API 來像訪問本地對象一樣來訪問 JavaScript 中的服務器端組件,以便通過方法調用發送和檢索數據。Seam Remoting 使用定制的、非 JSF 生命周期來使該浏覽器能夠與服務器端的組件通信。只有 Seam 容器和其組件可以在這些請求期間被恢復。透明協議是 AJax,但您無需費心數據包如何傳輸的細節。
AJax4JSf 則通過完全隱藏 JavaScript 的使用讓抽象更進了一步。它將所有邏輯都包裹在基本 UI 組件內。Ajax4jsf 通過完整的 JSF 生命周期接受 Ajax 請求。因而,支持 Ajax 的組件可以在不觸發浏覽器導航事件的前提下執行動作處理程序、升級 JSF 組件樹以及重新呈現該頁的某些部分。同樣地,通信也是通過 Ajax 實現的,但所有這些均在後台發生,頁面開發人員不可見。Ajax4JSf 面向組件的方法讓 AJax 功能得以成為 JSF 很自然的一部分,而不是格格不入的外來者。
我將深入探究這些方式,但我們還是先來看看 AJax 的基礎知識吧。