JSF 和 Ajax:使用 Rational Application Developer V7 輕鬆實現 Web 2.0 應用程式

來源:互聯網
上載者:User
Ajax 是當今互連網上最流行的技術,因為它被稱作 Web 2.0 的基石。不幸的是,建立 Ajax 應用程式並不容易,尤其是當您需要與其他架構融合時,例如 JavaServer Framework (JSF)。幸運的是,IBM Rational Application Developer V7 為 JSF 組件提供了 Ajax 功能,這一功能使得這樣的任務變得簡單。本文介紹了如何在 IBM Rational Application Developer V7 中使用 Ajax 和 JSF 以降低任務的難度,並通過一個例子示範如何在現存的應用程式中增加 Ajax 支援。

Ajax 的優勢和缺點

雖然不是什麼革新性創新,Ajax 技術在近兩年變得非常流行。大量主要 Web 網站(例如 Google、Yahoo!、 Amazon 和 Netflix)使用這一技術來改善它們網站使用者的訪問體驗。事實上,改進使用者體驗正是 Ajax 要做的。

在過去十年的 Web 應用程式開發中,使用者與瀏覽器間和瀏覽器與伺服器間的互動是明確界定及顯而易見的: 使用者在瀏覽器內瀏覽網頁,執行操作(從操作功能表中選擇內容,或者選擇一些複選框), 之後通過點選連結或提交按鈕指導瀏覽器與伺服器通訊。瀏覽器給伺服器發送請求並傳遞使用者輸入。伺服器處理請求並返迴響應,返回的可能是更新的頁面或是相同的頁面,總之進行了更新。

這樣的 Web 應用程式現在被稱為 Web 1.0。 從使用者體驗的觀點來看,它們具有兩條缺陷:

  • 瀏覽器和伺服器的互動只能由頁面中有限的控制項發起——常常是連結和按鈕。這樣就不能在使用者選擇了複選框(check box)或在組合框(combo box)後迅速通知伺服器。
  • 瀏覽器和伺服器的這種互動所造成的後果就是需要更新整個瀏覽器視窗。這種情況通常很慢,頁面更新往往需要使用者等待很長時間。更壞的是,當同一頁面被重新載入或重新重新整理時,經常會在瀏覽器視窗中閃爍。

新一代被稱為 Web 2.0 的 Web 應用程式通過利用 Ajax 技術彌補了這些缺點(也作AJAX,即 Asynchronous JavaScript and XML,非同步 JavaScript 與 XML)。在 Ajax 中,瀏覽器和伺服器的互動發生在後台,使用者將不會覺察。而且它比普通的“瀏覽器 - 伺服器”互動更具針對性,僅僅需要將頁面的子集發送給伺服器,並且伺服器僅僅返回所需更新的子集頁面。這種方式所帶來的結果就是,瀏覽器和伺服器間的通訊可被任何事件初始化,例如在組合框或複選框中進行選擇,或滑鼠指標停留事件等。這樣帶來了很大好處:

  • 通訊更加迅速,因為傳遞的資料更少。
  • 使用者停留在同一頁面,因為不再需要過多的頁面間導航。
  • 重新載入的頁面不會閃爍,因為僅僅是頁面中的一小部分依據 Ajax 請求更新。

Ajax 背後的想法十分簡單:在瀏覽器中監聽事件,給伺服器發送後台請求,當伺服器響應時更新頁面的一部分。但是實現過程是非常複雜的。它需要 JavaScript,用戶端-服務端通訊協定,和服務端代碼的深層知識。不同瀏覽器版本間的區別使得開發與調試更加困難。但是,IBM Rational Application Developer Version 7 提供了所有開發 Ajax Web 應用程式所需的工具,而 不必 實現所有底層細節。

Rational Application Developer V7 提供了:

  • 擴充的 JSF 允許在 JavaServer Framework (JSF)中處理 Ajax 請求
  • 一個可以在所有最新版本的主流瀏覽器中初始化 Ajax 請求,並在伺服器端響應僅對部分頁面進行更新的 JavaScript 程式庫

Rational Application Developer V7中 Ajax 和JSF 實現的技術細節超出了本文的範圍,但是讓我們來看看您如何使用這些技術。


如何用JSF組件應用Ajax

為 JSF 頁面增加 Ajax 需要四個步驟:

  1. 識別由 Ajax 請求更新的頁面地區。 在 Rational Application Developer V7中, 您可以在幾乎任何面板組件的內容中使用 Ajax。面板包括了從簡單的容器,例如 <h:panelGroup><h:panelGrid>,到特性豐富的面板,例如菜單 (<hx:panelMenu>) 和對話方塊(<hx:panelDialog>)。
  2. 選擇所使用的 Ajax 請求類型。 Rational Application Developer V7 JSF 庫支援三種 Ajax 請求:
    • 對於同一頁面的 GET 請求 (<hx:ajaxRefreshRequest>)
    • 對於同一頁面的 POST 請求 (<hx:ajaxSubmitRequest>)
    • 對其他頁面的 GET 請求 (<hx:ajaxExternalRequest>)
  3. 應用 Ajax 請求配置傳遞給伺服器的參數。
    • 對於 GET 請求,您可以傳遞頁面中不同輸入欄的值。
    • 對於 POST 請求, 提交全部表格。
  4. 識別初始化 Ajax 請求的事件。 它可以是任何的用戶端 JavaScript 事件,例如按鈕的 onclick , 輸入欄的 onblur, 或複選框的 onchange

讓我們通過“Hello, world”這個簡單的例子瞭解一下全部過程。建立一個頁麵包括兩欄:輸入和輸出。在使用者點中輸入欄後,將利用 Ajax 技術發送使用者輸入資料到伺服器,並且接收返回訊息更新輸出欄。

建立 Web 項目

首先,建立一個 Web 項目(參見 圖 1):

  • 從菜單選擇 File > New > Project > Dynamic Web Project
  • New Project 嚮導中:
    1. 輸入項目名稱(例如,HelloWorld)。
    2. 選擇 Faces Project 配置。
    3. 選擇 Add project to an EAR
  • 點擊 Finish

圖 1. New Dynamic Web Project 截屏

建立一個 Web 頁面(參見圖 2):

  • Project Explorer 中右擊 project name
  • 從操作功能表選擇 New > Web Page
  • New Web Page 嚮導中,輸入頁面名稱(例如,hello)。
  • 點擊 Finish

圖 2. New Web Page 嚮導

為頁面增加組件

既然已經有了頁面,您需要增加組件。您需要在文本欄使用 inputText 組件,outputText 組件顯示返回內容。因為要用 Ajax 更新 outputText ,您需要將其放入面板組件。本頁中要用到 panelGroup 組件。

增加組件的方法:

  • 從組件板的 Enhanced Faces Components中將 Input 組件拖到頁面上。
  • 從組件板中將 Panel Group box 組件拖到 Input 組件下。當激發群組方塊時,選擇 Group
  • 從組件板中將 Output組件拖到 Panel Group 框。

增加 Ajax 支援面板

為使面板內容可通過 Ajax 更新(本例中,是 Output 欄),您需要將面板標記為 "Ajaxable" ,並且為傳遞給伺服器的使用者請求配置參數。(參見 圖 3。)

  1. 選擇 outputText 組件,並切換回 Properties 視圖。
  2. 在 Properties視圖中,選擇 h:panelGroup 標籤,它處於左邊導覽列 h:outputText標籤正上部。
  3. 選擇 Ajaxh:panelGroup 標籤。
  4. 點擊 Allow Ajax updates 複選框。
  5. 選擇 Refresh 作為Ajax請求輸入。

圖 3. panelGroup 屬性

本例使用 Refresh 請求表示參數如何用 Ajax 請求傳遞。或者,Submit 請求將提交全部表格。由於例子頁面的表格僅包括了一個輸入欄,所以您無需為 Ajax 請求配置參數。

為了給 Ajax 請求配置參數(圖 4):

  • 在 Ajax 屬性頁面選擇 Click to edit Ajax request properties (參見 圖 3, 如前所示)。
  • Properties 頁面的 hx:ajaxRefreshRequest 標籤:
    1. 點擊 Add Parameter 從瀏覽器發送參數。
    2. 在組合框中選擇 Input 組件的名稱(本例中,text1)。

圖 4. ajaxRefreshRequest 屬性

您已經配置了由 Ajax 請求更新的 panelGroup 標籤,並使用 Input 欄的值作為請求參數。剩下的就是使得 outputText 組件使用這一參數顯示返回(參見 圖 5):

  • 選擇 outputText組件。
  • Value 欄輸入 Hello, #{param.text1}

圖 5. outputText Properties

初始化 Ajax 請求

如果您回顧應用 Ajax 所需的 四步,您會發現已經完成了前三步。現在,您僅需要識別可以觸發 Ajax 需求的事件。為更新返回,您需要在 inputText 組件使用 onblur 事件(參見 圖 6):

  • 選擇 inputText 組件。
  • 返回 Quick Edit 視圖。
  • 在 Quick Edit 視圖中:
    1. 左面事件列表中選擇 onblur 事件。
    2. 點擊 Use predefined behavior 複選框。
    3. 選擇 Invoke Ajax behavior on the specified tag 動作。
    4. 選擇 panelGroup 的名稱作為目標(本例中,group1)。

圖 6. Quick Edit 視圖

現在,您可以儲存頁面並在伺服器上運行。當開啟瀏覽器視窗時,可以在輸入欄下面看到“Hello” 文字。一旦使用者在其中輸入任何字元,傳回值將會更新輸入欄中的內容。(參見 圖 7。)

圖 7. 伺服器上運行 Web 頁面

正如您所見到的,您可以不必書寫任何 JavaScript 代碼而利用標準 JSF 組件實現一個簡單有效 Ajax 頁面。

下面,讓我們再看一個複雜一些的例子。


如何為現有 JSF 應用程式增加 Ajax

考慮一個普通的現代電子商務 Web 應用程式系統:購物車。如果您曾經有過網上購物的經曆,您一定已經看到過它。一個典型的購物車會顯示使用者瀏覽網站時加入的產品列表,可以改變數量的輸入欄,結帳按鈕等等。

如果您看過各種各樣的購物車,您可能會發現至少有兩點相同:

  • 總有一個根據使用者輸入的數量來更新的按鈕,用以重新計算總量、稅和價格。
  • 購物車中的商品條目都會提供一個連結以提供產品詳細資料的頁面。

這裡就有文章開始我們所提到的缺陷的執行個體。購物車僅當使用者點擊按鈕時才會更新,而使用者不得不轉入其他頁面以瀏覽產品的詳細描述。而在 Ajax 的協助下,使用者體驗可以得到大幅改進,因為只要數量發生變化總量就會自動更新,而產品詳細資料可以在同一頁面中得到顯示(也許在指定地區,也許在一個快顯視窗中)。

本文結尾部分的參考資源部分中,有一個 可下載的項目示範了如何輕鬆地將 Web 1.0 的購物車轉變為一個 Web 2.0 的應用程式。現在我們來瞭解一下這個例子,從而可以看到它是如何被構建的,如何使用 Ajax 加以修改的。

注意: 從這時起,所有涉及的東西 (JavaServer Pages [JSP] 名稱、組件 ID, 等等) 都是您可以下載的 AjaxSample 的應用程式。請儲存 AjaxSample.zip 檔案,之後使用 Project Interchange 格式將它匯入 Rational Application Developer V7 。

購物車:舊的方式

本例中的購物車使用三種 Java beans: Product、CartItem 和 ShoppingCart。 您能夠在 Project Explorer 中的 Java Resources 類下的 beans 包找到它們。

  • Product 包括了網站銷售的產品資訊:ID、名稱、描述、圖片和價格。
  • CartItem 跟蹤購物車中每件商品的數量。
  • ShoppingCart 記錄了購物車條目列表(商品和數量對); 計算總數,稅和價格; 並且協助使用者根據 ID 尋找商品。

如 圖 8 顯示, cart.jsp 是一種極為簡單的購物車頁面的實現方法。

圖 8. 購物車

頁面使用 dataTable 組件顯示購物車中的所有條目。 Quantity 列使用 inputText 欄改變數量。在使用者做出所有修改後,他們可以點擊 Recalculate 按鈕更新總量、稅和價格。商品名稱為使用者提供了進入其他頁面的連結以瞭解商品詳細資料——product.jsp。 商品 ID 作為參數傳遞。(參見 圖 9。)

圖 9. 商品詳細資料

購物車:新的方式

在這裡,cartajax.jsp 是相同的購物車頁面,但它被重新設計了,利用 Ajax 改善了使用者體驗。新 cartajax.jsp (圖 10) 和老 cart.jsp 有三點明顯的不同:

  • 沒有 Recalculate 按鈕。一旦使用者焦點離開輸入欄就會更新總量。
  • 當使用者滑鼠指標移到商品名上時,商品描述會顯示在快顯視窗中。
  • 當使用者點擊商品連結時,商品的所有詳細資料會顯示在購物車下,而不用更新購物車本身。

圖 10. 包含 Ajax 的購物車

讓我們看看這種變化如何發生的。為瞭解釋的目的,這一頁面使用了所有三類 Ajax 請求。而且,與本文開始僅使用 IDE 屬性建立 Ajax 功能不同,這裡您可以看到 Source 模式中的 JSF 標籤。

去掉 Recalculate 功能

不必使用 Recalculate 按鈕,您將包括了總量、稅、價格的面板使用 ajaxSubmitRequest 標籤聲明為 "Ajaxable" ,如 列表 1 所示。

列表 1. ajaxSubmitRequest 代碼

            <h:panelGrid id="totals" styleClass="panelGrid" columns="2" style="text-align:right;">            <h:outputText id="text4" styleClass="outputText" value="Sub-total:"></h:outputText>            <h:outputText id="textTotalPrice" value="#{cart.totalPrice}" styleClass="outputText">            <hx:convertNumber type="currency" />            </h:outputText>            ... other output components ...            </h:panelGrid>            <hx:ajaxRefreshSubmit id="refreshTotals" target="totals"></hx:ajaxRefreshSubmit>            

您這裡正使用 Ajax 的 Submit 類型,因此不需傳遞任何參數,因為全部購物車表格將被提交。這就使得伺服器端代碼可以使用所有輸入欄中的數量。這一面板和 Ajax 標籤由 ID 和目標屬性串連在一起,它們在本例中是粗體突出的(列表 1)。 一旦使用者焦點離開輸入欄,總數就會更新。因此,您可以使用 inputText 組件的 onblur 事件初始化請求:

列表 2. 通過 Ajax 初始化 Submit 請求的代碼

            <h:inputText id="textQuantity1" value="#{varproducts.quantity}" styleClass="inputText"            size="3">            <hx:behavior event="onblur" behaviorAction="get" targetAction="totals">            </hx:behavior>            </h:inputText>            

hx:behavior 標籤是一種十分有效串連預定義 JavaScript 功能和用戶端 JSF 組件事件的方法。本例中,您使用的是 inputText 組件(hx:behaviorh:inputText 的子集)的 onblur 事件(事件屬性), 並且希望執行 totals 組件的 get 行為。這裡,Totals 是需要更新的面板,get 行為表示“擷取內容”,因此:使用 Ajax 更新。

注意:選擇 cartajax.jsp 然後 Run On Server 會發現瀏覽器中的這些標記工作在一起。

一旦焦點離開表中任意輸入欄,就會運行與 onblur 事件聯絡的 JavaScript 代碼。 它會發現頁面上的 Totals 組件,核實具有與其聯絡的 ajaxRefreshSubmit 組件,之後通過給伺服器發送表格的形式初始化 Ajax POST 請求。 當伺服器響應時,Totals 面板會更新為來自於伺服器的新內容。

增加彈出描述

下一個例子使用無模型 Dialog 組件(Rational Application Developer V7 中的新組件)顯示購物車中的條目描述。由於 Dialog 是一個面板,它的內容更新可使用與 panelGroup 和 panelGrid 組件相同的 Ajax更新方式(列表 3):

列表 3. 使用新的 Dialog 組件顯示商品描述資訊

            <hx:panelDialog type="modeless" id="descriptionPopup" styleClass="panelDialog"            style="background-color: #fff9ca" movable="false"            align="relative" valign="relative" saveState="false"            showTitleBar="false">            <h:outputText id="textDescription1d"            value="#{cart.selectedProduct.description}"            styleClass="outputText">            </h:outputText>            </hx:panelDialog>            <hx:ajaxRefreshRequest id="showPopup" target="descriptionPopup"            params="$$AjaxROW$$form1:tableEx1:itemid"></hx:ajaxRefreshRequest>            

這與之前的標籤十分相似,除了這次使用 Ajax 的 Refresh 類型。 因此,您需要為伺服器傳遞一個參數 -- 特別是您想看的商品資訊的購物車條目 ID。因為您的條目在一個 dataTable 中, 而JSF僅記錄表中每個組建的一個執行個體,因此必須讓伺服器端代碼知道您需要使用 active 行中的組件值,表示這一行產生請求。為實現它, 需要在ID組件前放入 $$AjaxROW$$

為了當使用者停留在條目上時顯示或隱藏對話方塊,您可以使用 Link 組件的 onmouseoveronmouseout 事件, 正如 列表 4所示:

列表 4. 當使用者滑鼠指標停留在條目上時顯示或隱藏對話方塊的代碼

            <h:outputLink id="link1">            <h:outputText id="textName1" value="#{varproducts.product.name}"            styleClass="outputText">            </h:outputText>            <hx:behavior event="onmouseover" behaviorAction="get;show"            targetAction="form1:descriptionPopup;form1:descriptionPopup"></hx:behavior>            <hx:behavior event="onmouseout" behaviorAction="hide"            targetAction="form1:descriptionPopup"></hx:behavior>            </h:outputLink>            

當使用者滑鼠指標經過條目上時,你想更新對話方塊內容(get行為)並且顯示這個對話方塊(show 行為)。 當滑鼠指標離開條目時,你想隱藏這個對話方塊(hide 行為)。

在同一頁面顯示商品詳細資料

最後一步改進就是在同一頁面的購物車下顯示商品詳細資料。 您已有顯示一個條目的詳細資料的頁面:product.jsp。 因此, 您不必重新設計與實現 cartajax.jsp 中相似的標記。 您可以在第三類 Ajax 請求的類型的協助下使用現有的 JSP 檔案:External 請求 (參見 列表 5 ):

列表 5. 在同一頁面顯示商品詳細資料的代碼

                 <h:panelGrid id="product" width="700" style="margin-top: 20px;"            styleClass="panelGrid">            <h:outputText id="text8" styleClass="outputText"            value="Click on a product to see its details here."            style="color: gray; font-size: 10pt">            </h:outputText>            </h:panelGrid>            <hx:ajaxExternalRequest id="showDetails" target="product"            href="product.faces" source="product"            params="$$AjaxROW$$form1:tableEx1:itemid">            </hx:ajaxExternalRequest>            

您可能已經意識到這種模式: 一個面板組件和一個關聯的 Ajax 標記。 panelGrid 產品如同儲存商品的詳細資料一樣。如果使用者沒有選擇商品,她僅僅為使用者解釋頁面中各部分的用途。當使用者點擊了一個商品,面板內容就會根據 panelGrid 更新,與 product.jsp 檔案中定義的相似(href 屬性)。

這時,Link 組件的onclick 事件初始化了 Ajax 請求,如 列表 6 所示:

列表 6. 使用 onclick 事件初始化 Ajax 請求的代碼

            <h:outputLink id="link1">            <h:outputText id="textName1" value="#{varproducts.product.name}"            styleClass="outputText">            </h:outputText>            <hx:behavior event="onclick" behaviorAction="get;stop"            targetAction="product">            </hx:behavior>            </h:outputLink>            

行為中的第二個動作 (stop) 是為了阻止瀏覽器中的泡沫事件。您不會想本例中看似正常的連結僅僅初始化了一個 Ajax 請求後就停止了處理事件。

您需要做的最後一點改變是如何使當前所選的商品 ID 傳遞到伺服器端。在購物車的 cart.jsp 版本中(此時使用一個連結導向另一頁面),您將 ID 定義為串連參數(列表 7):

列表 7. 最初的購物車中 ID 定義為參數的串連

            <h:outputLink id="link1" value="product.faces">            <h:outputText id="textName1" value="#{varproducts.product.name}"            styleClass="outputText">            </h:outputText>            <f:param name="itemid" id="param1" value="#{varproducts.product.id}" />            </h:outputLink>            

但使用 Ajax 時, 您不再需要真實的串連,只需使用 Ajax 標記的 params 屬性傳遞組件值。因此,不必在串連中包含參數,您只需建立一個包括了緊鄰串連的 ID 的組件值,且將這一組件作為 Ajax 參數(參見 列表8):

列表 8. 建立一個隱藏的 ID 輸入欄作為 Ajax 參數

            <h:outputLink id="link1">            <h:outputText id="textName1" value="#{varproducts.product.name}"            styleClass="outputText">            </h:outputText>            </h:outputLink>            <h:inputHidden id="itemid" value="#{varproducts.product.id}" />            <hx:ajaxExternalRequest id="showDetails" target="product"            href="product.faces" source="product"            params="$$AjaxROW$$form1:tableEx1:itemid">            </hx:ajaxExternalRequest>            

完成了這個改變,您就完成了對購物車的修改。



回頁首

其他使用 Rational Application Developer Ajax 工具的方式

雖然您所做的改變示範了 JSF 標籤,但僅僅出於解釋的目的,在 Rational Application Developer 中您可以很容易的通過拖拽,Properties 視圖,Quick Edit 視圖複製它們。 這與本文開始部分構建“Hello, world”的過程完全相同。因此,正如您看到的, 您可以改進應用程式的可用性,而不必扔掉任何已有的工作。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.