<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    周游世界

    喂馬, 劈柴, 周游世界

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      28 隨筆 :: 0 文章 :: 4 評論 :: 0 Trackbacks
    JSF for Nonbelievers: Clearing the FUD about JSF -- Richard Hightower
    來自:http://www-128.ibm.com/developerworks/library/j-jsf1/
    翻譯:zhouy
    --------------------------------------------------------------------------------
    恐懼、不確定和懷疑
    JSF 的觀念環繞著 JSF 技術已經有一段時間了,我覺得是阻止這種觀念繼續曼延的時候了——或者至少在兩者這間取得平衡點。關于 JSF ,首當其充的誤解,就是離不開拖拽式所見即所得工具進行 JSF 開發。其二, JSF 不支持類似 Struts MVC Model 2 框架。而最后一點,也是困擾 JSF 開發最大的一點,就是關于其開發困難度的說法。

    在這個四小節的討論中,我將盡我所能,通過教你如何利用JSF進行開發這種最實際的方法,來消除上述所有三種誤解。事實上,如果你覺得JSF開發是件困難的事,那么很有可能是因為你沒有正確的使用它——幸運的是要修正它并不難。我會讓你對JSF有一個大體的觀念,并且利用一個可工作的示例展示MVC和JSF的基本原理。在我們開始所有介紹之前,先花一分鐘時間將事實不符的FUD區分清楚。

    不要相信FUD

    如前面提到的,關于JSF有三個大的誤解,其一便是JSF要求所見即所得工具進行開發工作。這是錯誤的,就像許多Swing開發人員不使用所見即所得工具構建Swing應用程序一樣,你不必需要所見即所得編輯器來構建JSF應用。事實上,不使用所見即所得工具來開發 JSF 會比傳統的Model 2框架如Struts和WebWork開發來得簡單。在稍后的章節中我會有詳細的解釋,但在這里請記?。篔SF開發比Struts來得簡單,即使不使用所見即所得工具!

    關于JSF的另一個誤解是,它不支持Model 2模型?,F在,這種說法只是部分正確。事實是Model 2是一種建立在Servlets基礎上的MVC瀑布模型版本。與Model 2面向無狀態協議(HTTP)所不同的是,JSF支持富MVC模型——一種與傳統的GUI應用更加相似的模型。雖然MVC的基礎概念使得JSF框架的實現比其它框架困難,但在上層結構上許多實現JSF的工作已經為你做好,得到的結果是,付出減少,卻能夠獲得更多的回報。

    流傳最廣的關于JSF的誤解是在于JSF的開發難度。我經常從人們口中聽到這樣的說法,他們閱讀了大量的技術文檔,但是并沒有實際動手去嘗試這項技術,所以我認為要消除這個慮慮很簡單。如果你是通過 JSF 浩瀚無邊的規格說明來建立你對JSF的理解,那么這些東西肯定會使你受驚嚇。要明確的是,所有的這些規格本質上是給實現工具使用的,而不是應用程序開發者。如前所述,JSF是為方便應用程序開發者而設計的。

    雖然從某種意義上說,JSF的組件基礎和事件驅動的GUI式的開發模型對于Java世界來說是一種新鮮的事物,但是它其實早已在某些領域中存在了。Apple的WebObjects和ASP.net與JSF就十分的相似。Tapestry是一項開源的Web組件框架,它與JSF所采用的方法不同,但也是一種基于Web GUI組件框型的技術。

    無論如何,關于FUD的討論或許可以終止。解決關于JSF的編見最快捷的方法便是正確地研究這門技術,這正是我們稍后要做的事情??紤]到這或許是你第一次了解JSF,我將為你介紹它的總體概念。

    給JSF初學者

    類似于Swing和AWT,JSF提供了一套標準和可重用的GUI組件。JSF被用來構建Web應用表層,它提供如下開發優勢:

    • 動作邏輯與表現邏輯的明顯區分
    • 有狀態事務的組件級別控制
    • 事件與服務端代碼的輕松綁定
    • UI組件及Web層觀念
    • 提供多樣的、標準的開發商實現規則
    一個典型的JSF應用包括以下幾個部分:
    • 供管理應用狀態和動作的JavaBeans組件
    • 事件驅動開發(通過與傳統GUI開發類似的監聽器來實現)
    • 展示MVC樣式的頁面,通過JSF組件樹引用視圖
    雖然你將需要克服使用JSF過程中的觀念上的困難,但是這些努力都將是值得的。JSF的組件狀態管理,方便的用戶輸入校驗,小粒度,組件基礎的事件處理及方便的可擴展框架將使你的Web開發便得簡單。我將在接下來的幾章中用最詳細的解釋說明這些最重要的特征。

    組件基礎的框架模式

    JSF為標準HTML中每個可用的輸入域提供了組件標簽,你也可以為你應用中的特殊目的定義自己的組件,或者也可以將多項HTML組件組合起來成為一個新的組合——例如一個數據采集組件可以包含三個下拉菜單。JSF組件是有狀態的,組件的狀態由JSF框架來提供,JSF用組件來處理HTML響應。

    JSF的組件集包含事件發布模型、一個輕量級的IoC容量、擁有其它普遍的GUI特征的組件,包括可插入的渲染、服務器端校驗、數據轉換、頁面導航控制等等。作為一種基于組件的框架,JSF極具可配置性和可護展性。大部分的JSF功能,比如導航和受管bean查詢,可以被可插入組件所替換。這樣的插入程度給開發人員構建Web應用GUI時提供了極大的彈性,允許開發人員將其它基于組件的技術應用于JSF的開發過程中來。比如說,你可以將JSF的內嵌IoC框架替換為更加全能的Spring的IoC/AOP以供受管bean查詢。

    JSF和JSP技術

    一個JSF應用的用戶表層被包含在JSP(JavaServer Pages)頁面中。每個JSP頁面包含有JSF組件,這些組件描繪了GUI功能。你可以在JSP頁面里使用 JSF 定制標簽庫來渲染UI組件,注冊事件句柄,實現組件與校驗器的交互及組件與數據轉換器的交互等等。

    那就是說,JSF不是固定與JSP技術相關聯。事實上,JSF標簽僅僅引用組件以實現顯示的目的。你會發現當你第一次修改一個JSP頁面中某一JSF組件的屬性,在重新載入頁面的時候并沒有發生應有的變化。這是因為標簽在它自己的當前狀態中進行查詢,如果組件已經存在,標簽就不會改變它的狀態。組件模型允許控制代碼改變一個組件的狀態(例如將一個輸入域置為不可用),當視圖被展現的時候,組件樹的當前狀態也隨著一覽無余。

    一個典型的JSF應用在UI層無需任何的Java代碼,只需要很少的一部份JSTL EL( JSP 標準標簽庫,表達式語言)。前面已經提及,有非常多IDE工具可以幫助我們構建JSF應用,并且有越來越多的第三方JSF GUI組件市場。不使用所見即所得工具來編寫JSF也是可行的。

    JSF和MVC

    JSF技術是在多年Java平臺上的Web開發技術的總結的產物。這種趨勢起源于JSP。JSP是一種很好的表現層,但同時它容易將Java代碼與HTML頁面混淆起來。另一個不好的原因與Model 1架構有關,它使得開發人員通過使用 <jsp:useBean> 標簽將許多原本應該在后端處理的代碼引入到Web頁面中來。這種方法在簡單的Web應用中可以運行得很好,但許多Java開發者不喜歡這種類似C++的靜態引入組合方式,所以Model 2架構隨之被引進。

    本質上,Model 2架構是MVC Web應用的一種瀑布模型版本。在Model 2架構中控制器通過Servlets來表現,顯示層則通過JSP頁面來展現。Struts是一種最簡單的Model 2實現,它使用Actions取代了Servlets。在Struts中應用的控制邏輯與數據層(通過ActionForms來展現)相分離。反對Struts的主要的不滿在于,Struts更多偏向程序化,而非面向對象。WebWork和Spring MVC是Model 2的另外兩種框架,它們比起Struts更大的改進在于盡量減少程序化,但是兩者都沒有Struts普及。另外兩者也不像JSF般提供組件模型。

    大多數Model 2框架真正的因素在于它們的事件模型顯得過于單薄,留下了太多的工作需要開發人員自己來處理。一個富事件模型使多數用戶所希望的交互變得簡單。許多Model 2技術就像JPS一樣,很容易將HTML布局及格式與GUI標簽相混合,在表現上不像真正的組件。而一些Model 2的架構(如Struts)錯誤地將表現與狀態分離,便得許多Java開發人員感覺他們像是在編寫COBOL程序。

    富MVC環境

    JSF提供一種組件模型及比其它Model 2實現更為豐富的MVC環境。本質上說,JSF比Model 2架構更接近真正的MVC開發環境,雖然它仍然屬于無狀態協議。JSF能夠構建比起其它Model 2框架更精彩的事件驅動 GUI 。JSF提供一系列事件選項如menu選項的selected事件,button的clicked事件等等,這與在其它Model 2框架中更多地依賴簡單的“request received”不同。

    JSF的易于翻轉的事件模型允許應用程序更少地依賴HTTP實現細節,簡化你的開發量。JSF改善了傳統Model 2架構,它更容易將表現層和業務層移出控制器,并將業務邏輯從JSP頁面中移出。事實上,簡單的控制器類根本無需與JSF相關聯,方便了對控制器類的測試。與真正的MVC架構不同,JSF不會在多于一個視點上發出多條事件,我們仍然是在處理一個無狀態的協議,這使得這一點變得無關緊要。系統事件對一個視圖的變動或更新通常來自于用戶的請求。

    JSF的MVC實現細節

    在JSF的MVC實現中,作為映射的backing bean在視圖和模型間扮演著協調的作用。正因如此,在backing bean里限制業務邏輯和持久層邏輯就顯得猶為重要。一種普遍的做法是將業務邏輯置入應用模型中。這樣的話backing bean仍會映射模型對象以供視圖顯示。另一種選擇是將業務邏輯放入業務代理——一種與模型相作用的表層。

    與JSP技術不同,JSF的視圖實現是一種有狀態組件模型。JSF的視圖由兩部分組成:根視圖和JSP頁面。根視圖是UI組件的集合,它負責維護UI的狀態。就如像Swing和AWT,JSF組件使用組合式設計模式來管理組件樹,用按鈕來管理事件句柄及動作方法。

    Figure 1 通過MVC角度來透析的示例


    ?

    一個 JSF 例子

    在文章剩余的章節里,我將專注于構建一個 JSF 應用的過程。這個例子是 JSF 技術的一個非常簡單的展現,主要表現在以下幾個方面:

    • 如何設置 JSF 應用程序的格局
    • 如何為 JSF 配置 web.xml 文件
    • 如何為程序配置 faces-config.xml 文件
    • 編寫模型(即 backing bean
    • 利用 JSP 技術構建視圖
    • 利用傳統標簽庫在根視圖框建組件樹
    • Form 的默認校驗規則

    例子是一個簡單的計算器程序,使目標用戶能夠輸入兩個數并計算。因此頁面上有兩個文本域,兩個標簽,兩處錯誤提示和一個提交按鈕。文本域用來輸入數字,標簽用來標示輸入的文本域,錯誤提示用來顯示文本域中的輸入在校驗或數據轉換時出現的錯誤。總共有三個 JSP 頁面: index.jsp 用來重定向到 calculator.jsp 頁面; calculator.jsp 用來顯示上面提及的 GUI ; result.jsp 用來顯示最后結果。一個受管 bean CalculatorController 作為 calculator.jsp result.jsp backing bean 。

    ? Figure 2 示例程序的第二張 MVC 視圖


    構建應用
    ?
    為了構建計算器程序,你需要如下步驟:

    1. ? 收集 web.xml faces-config.xml 文件,可以在下面的示例源代碼中找到。
    2. web.xml 中聲明 Faces Servlet Faces Servlet 映射。
    3. web.xml 中指定 faces-config.xml
    4. faces-config.xml 中聲明受管于 JSF bean 。
    5. faces-config.xml 中聲明導航規則。
    6. 構建模型對象 Calculator 。
    7. CalculatorController Calculator 交互。
    8. 創建 index.jsp 頁面。 ?
    9. 創建 calculator.jsp 頁面。
    10. 創建 results.jsp 頁面。

    聲明 Faces Servlet Servlet 映射
    ?

    為了使用 Faces ,你需要在 web.xml 中裝載 Faces Servlet 如下:

    <!-- Faces Servlet -->
    <servlet>
    ? <servlet-name>Faces Servlet</servlet-name>
    ? <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    ? <load-on-startup>1</load-on-startup>
    </servlet>

    這和大多數web.xml描述文件類似,所不同的是將request的掌握權轉向JSF Servlet,而非自定義的Servlet。所有請求引用了f:viewJSP文件的request都將通過此Servlet。因此需要增加相應的映射,并且將允許使用JSFJSP技術通過映射裝載進來。

    <!-- Faces Servlet Mapping -->
    <servlet-mapping>
    ??? <servlet-name>Faces Servlet</servlet-name>
    ??? <url-pattern>/calc/*</url-pattern>
    </servlet-mapping>

    以上配置告知Faces Servlet容器將所有符合/calc/的請求都轉給Faces Servlet處理。這使得JSF能夠初始化JSF內容和根視圖。

    定義faces-config.xml文件

    如果你將你的faces配置文件命名為faces-config.xml并將其放置在WEB-INF目錄下,Faces Servlet會查找到它并自動使用它?;蛘吣阋部梢酝ㄟ^web.xml?中的一個初始化參數裝載一個或多個應用配置文件——javax.faces.application.CONFIG_FILES——通過逗號將作為參數的文件列表分隔開來?;蛟S你會使用第二種方法為所有的JSF應用程序作配置。

    聲明bean管理

    接著是聲明哪個beanJSF GUI組件所使用。在示例中只有一個受管bean,在faces-config.xml中配置如下:
    <faces-config>
    ?? ?...
    ? <managed-bean>
    ??? <description>
    ????? The "backing file" bean that backs up the calculator webapp
    ??? </description>
    ??? <managed-bean-name>CalcBean</managed-bean-name>
    <managed-bean-class>
    ?? ?com.arcmind.jsfquickstart.controller.CalculatorController
    </managed-bean-class>
    ??? <managed-bean-scope>session</managed-bean-scope>
    ? </managed-bean>
    </faces-config>

    上面的配置告知JSF要往JSF環境中增加一個叫做CalcBeanbean,你也可以把受管bean取任何名字。Bean已經聲明了,然后你要做的就是為應用定義導航規則。

    定義導航規則

    這樣一個簡單的應用,你只需使導航規則從calculator.jspresult.jsp頁面即可。如下:

    <navigation-rule>
    ? <from-view-id>/calculator.jsp</from-view-id>
    ? <navigation-case>
    ??? <from-outcome>success</from-outcome>
    ??? <to-view-id>/results.jsp</to-view-id>
    ? </navigation-case>
    </navigation-rule>

    上面的代碼表明,如果一個動作從/calculator.jsp頁面返回邏輯輸出為“success”,那么它將用戶轉向/result.jsp頁面。

    ?視計模型對象

    ?由于我們的目標是介紹如何開始JSF,所以我將模型對象設計得非常簡單。這個模型包含在一個對象里,如Listing 1所示。

    ?Listing 1. The Calculator app's model object

    package com.arcmind.jsfquickstart.model;

    /**
    ?* Calculator
    ?*
    ?* @author Rick Hightower
    ?* @version 0.1
    ?*/
    public class Calculator {
    ??? //~Methods------------------------------------------------
    ??? /**
    ???? * add numbers.
    ???? *
    ???? * @param a first number
    ???? * @param b second number
    ???? *
    ???? * @return result
    ???? */
    ??? public int add(int a, int b) {
    ??????? return a + b;
    ??? }

    ??? /**
    ???? * multiply numbers.
    ???? *
    ???? * @param a first number
    ???? * @param b second number
    ???? *
    ???? * @return result
    ???? */
    ??? public int multiply(int a, int b) {
    ??????? return a * b;
    ??? }
    }

    這樣,業務邏輯就全部建立了。下一步便是將其顯示在
    Web表現層上。

    ?結合模型和視圖

    ?控制器的目的就是將模型與視圖結合在一起。控制器對象的一個作用就是保持模型與視圖的不可知論。(?)如同你在下面所看到的,控制器定義了三個JavaBeans屬性,通過這些屬些控制輸入和輸出結果。這些屬性是:results(作為輸出)、firstNumber(作為輸入)、secondNumber(作為輸入)。Listing 2CalculatorController的代碼。

    ?Listing 2. The CalculatorController

    package com.arcmind.jsfquickstart.controller;

    import com.arcmind.jsfquickstart.model.Calculator;

    /**
    ?* Calculator Controller
    ?*
    ?* @author $author$
    ?* @version $Revision$
    ?*/
    public class CalculatorController {
    ??? //~ Instance fields --------------------------------------------------------

    ??? /**
    ???? * Represent the model object.
    ???? */
    ??? private Calculator calculator = new Calculator();

    ??? /** First number used in operation. */
    ??? private int firstNumber = 0;

    ??? /** Result of operation on first number and second number. */
    ??? private int result = 0;

    ??? /** Second number used in operation. */
    ??? private int secondNumber = 0;

    ??? //~ Constructors -----------------------------------------------------------

    ??? /**
    ???? * Creates a new CalculatorController object.
    ???? */
    ??? public CalculatorController() {
    ??????? super();
    ??? }

    ??? //~ Methods ----------------------------------------------------------------

    ??? /**
    ???? * Calculator, this class represent the model.
    ???? *
    ???? * @param aCalculator The calculator to set.
    ???? */
    ??? public void setCalculator(Calculator aCalculator) {
    ??????? this.calculator = aCalculator;
    ??? }

    ??? /**
    ???? * First Number property
    ???? *
    ???? * @param aFirstNumber first number
    ???? */
    ??? public void setFirstNumber(int aFirstNumber) {
    ??????? this.firstNumber = aFirstNumber;
    ??? }

    ??? /**
    ???? * First number property
    ???? *
    ???? * @return First number.
    ???? */
    ??? public int getFirstNumber() {
    ??????? return firstNumber;
    ??? }

    ??? /**
    ???? * Result of the operation on the first two numbers.
    ???? *
    ???? * @return Second Number.
    ???? */
    ??? public int getResult() {
    ??????? return result;
    ??? }

    ??? /**
    ???? * Second number property
    ???? *
    ???? * @param aSecondNumber Second number.
    ???? */
    ??? public void setSecondNumber(int aSecondNumber) {
    ??????? this.secondNumber = aSecondNumber;
    ??? }

    ??? /**
    ???? * Get second number.
    ???? *
    ???? * @return Second number.
    ???? */
    ??? public int getSecondNumber() {
    ??????? return secondNumber;
    ??? }

    ??? /**
    ???? * Adds the first number and second number together.
    ???? *
    ???? * @return next logical outcome.
    ???? */
    ??? public String add() {
    ???????
    ??????? result = calculator.add(firstNumber, secondNumber);

    ??????? return "success";
    ??? }

    ??? /**
    ???? * Multiplies the first number and second number together.
    ???? *
    ???? * @return next logical outcome.
    ???? */
    ??? public String multiply() {

    ??????? result = calculator.multiply(firstNumber, secondNumber);
    ??? ???
    ??????? return "success";
    ??? }
    }

    請注意,在
    Listing 2中乘法和加法都返回“success”。“success”表明一個邏輯輸出,它不是保留字,它是與faces-config.xml的導航規則相結合的,通過增加或定義操作執行,頁面將轉向result.jsp

    ?這樣,你已經完成了后臺代碼工作。接下來我們將定義JSP頁面及組件樹以展示應用視圖。

    ?創建index.jsp頁面

    ?Index.jsp的目的是保證/calculator.jsp頁面被正確的裁入JSF內容中,使得頁面可以找到正確的根視圖。

    <jsp:forward page="/calc/calculator.jsp" />

    ?這個頁面全部所做的工作便是將用戶重定向到/calc/calculator.jsp頁面。這樣便將calculator.jsp頁面導向JSF內容中,使得JSF可以找到根視圖。

    ?創建calculator.jsp頁面

    ?Calculator.jsp是整個計算器應用程序的中心視圖。這個頁面獲取用戶輸入的兩個數字,如Figure 3所示。

    Figure 3. The Calculator page
    Calculator page

    ?

    這一頁較為復雜,我將一步一步進行講解。首先你需要聲明供JSF使用的標簽庫:

    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

    上述代碼告訴
    JSP引擎你將使用兩個JSF標簽庫:htmlcore。Html標簽庫包含所有與forms和其它HTML規范有關的標簽。Core標簽庫包含所有邏輯、校驗、控制等JSF標簽。

    ?一旦將頁面展示在普通的HTML中,你會告訴JSF系統你將使用JSF來管理你的組件。通過使用<f:view>標簽來實現這點,它會告知容器你將使用JSF來管理所有包含在它里面的組件。

    ?少了<f:view>JSF將無法構建組件樹,稍后也無法在已經創建起來的組件樹中進行查詢。通過以下代碼使用<f:view>

    <f:view>
    ? <h:form id="calcForm">
    ???? ...?? ?
    ? </h:form>
    </f:view>

    上面的第一行是<f:view>的聲明,告知容器它受管于JSF。下一行是<h:form>標簽,它告知JSF你需要在此建一個HTML FORM。在位于FORM組件內的組件容器的語法渲染期間,所有的組件將會被問詢自動渲染,這樣它們將會生成標準的HTML代碼。

    接下來,你告知JSFFORM里所需的其它組件。在<h:form>中定義了一個panelGrid。panelGrid是一個組合組件——也就是一個組件里包含有其它的組件。panelGrid定義其它組件的布局,Listing 3顯示如何定義panelGrid的代碼:

    Listing 3. Declaring the panelGrid

    <h:panelGrid columns="3">
    ? <h:outputLabel value="First Number" for="firstNumber" />
    ? <h:inputText id="firstNumber" value="#{CalcBean.firstNumber}" required="true" />
    ? <h:message for="firstNumber" />???
    ? <h:outputLabel value="Second Number" for="secondNumber" />
    ? <h:inputText id="secondNumber" value="#{CalcBean.secondNumber}" required="true" />
    ? <h:message for="secondNumber" />
    </h:panelGrid>

    屬性columns被定義為3表明所有組件將被布置在擁有3列空間的格局中。我們在panelGrid中加入了6個組件,共占2行。每一行包含一個outputLabel,一個inputText和一條messageLabelmessage都和inputText組件關聯,因此當一個校驗錯誤或或誤信息關聯到textField時,信息將會顯示在message組件上。兩個文本輸入域都要求有,如果在提交的時候檢測到無值,錯誤信息將會被創建,控制也將會轉到這個視圖來。

    注意到兩個inputFields都使用一條JSF表達式來做數值綁定。乍一看這很像一條JSTL表達式。但是,JSF表達式確實與綁定著后臺代碼相應字段的輸入域相關聯。這種關聯是反向的,如果firstNumber100,那么在form顯示的時候100也會被顯示。同樣,如果用戶提交一個有效的值,例如200,那么200也將作為firstNumber的新值。

    一個更加實用的目的是,后臺代碼通過綁定模型對象的屬性的值到輸入域中,從而將模型對象展現出來。你將在此節稍后看到關于此目的的例子。

    除了輸入域,calForm通過panelGroup中的兩個commandButton與兩個動作關聯:

    <h:panelGroup>
    ??? <h:commandButton id="submitAdd" action="#{CalcBean.add}"? value="Add" />
    ??? <h:commandButton id="submitMultiply" action="#{CalcBean.multiply}" value="Multiply" />
    </h:panelGroup>

    panelGroup的概念與panelGrid很相似,除了它們顯示方式的不同。命令按鈕利用action=”#{CalcBean.add}”將按鈕與后臺動作綁定在一起。因此當這個form通過這個按鈕提交的時候,相關聯的方法便開始執行。

    創建results.jsp頁面

    Results.jsp頁面是用來顯示最后計算結果。如Listing 4所示:

    Listing 4. The results.jsp page

    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
    ...
    <f:view>
    ? First Number: <h:outputText id="firstNumber" value="#{CalcBean.firstNumber}"/>
    ? <br />
    ? Second Number: <h:outputText id="secondNumber" value="#{CalcBean.secondNumber}"/>
    ? <br />
    ? Result: <h:outputText id="result" value="#{CalcBean.result}"/>
    ? <br />
    </f:view>

    Results.jsp
    是一個相對簡單的頁面,將加法運算的結果顯示給用戶。通過<h:outputText>標簽來完成這一功能。<h:outputText>標簽帶有idvalue屬性,value屬性輸出值,它在渲染的時候將被當作string看待。Value屬性通過JSF將要輸出的值與后臺代碼的屬性綁定在一起。

    ?運行程序!

    運行war文件所映射的程序。Index.jsp頁面將調用calculator.jsp,如果你在firstNumber域或secondNumber域中輸入非法文本(如“abc”)提交,你將返回到/calculator.jsp視圖并且相應的錯誤信息將會顯示在頁面上。如果你將firstNumbersecondNumber放空提交你也將會獲得相應的錯誤結果。由此可以看出在JSF許多校驗幾乎是自動定義,只要你將輸入域定義為required并且綁定相應的int屬性的字段即可。

    Figure 4顯示應用程序如何處理校驗和數據轉換數據。

    Figure 4. Validation and data conversion errors


    ?

    總結

    在這篇關于JSF的介紹中是否使你有些頭暈?不用擔心,你已經跨過了最壞的一道坎。了解JSF的框架概念是這場戰役的一半,有過之而無不及,而且你將會很快意識到它的價值。

    如果在閱讀的過程中你想象使用Struts實現上述代碼會更加簡單,我估計它會耗費至少兩倍精力。用Struts構建同樣的應用,你需要為兩個按鈕創建兩個action類,各自需要自己的對應的動作映射。而且需要一個動作映射來裝載首頁(假設你遵守Model 2的建議)。另外,模仿JSF默認的錯誤獲取和校驗機制,你需要為Struts配置校驗框架或者實現在ActionForm中實現等值的validate方法。你還必須在Struts配置中定義DynaValidatorForm或者建立一個ActionForm重寫validate方法,或者使用ValidatorForm的子類。最終,你或許(必須)需要為所有的action定義forward或者全局forward

    不止雙倍的代碼工作,Struts對于初學者來說意味著需要花費更多的精力。我之所以知道這點,是因為我寫過關于StrutsJSF課程的教材并且為我的學員們上過課。開發人員通常非常容易掌握JSF,但在學習Struts的過程中卻倍受折磨。我相信更多有遠見的人選擇JSF,而非Struts。直覺上說,JSF更加合理。Struts已經被擱置,JSF被列入技術清單。在我的書中,JSF開發過程是簡便的,并且比Struts更具有生產率。

    這是JSF系列的第一篇文章的總結。在下一篇文章里我會繼續這篇文章的話題,內容覆蓋JSFrequest處理生命周期,指明生命周期中同一應用程序的不同部分。我還將介紹immediate event handling的概念,并且讓你對JSF的組件事件模型有更全面了解,包括關于許多內嵌組件的討論。我還將談談有關JSFJavaScript相結合的話題,請關注下個月的文章。

    posted on 2006-07-17 20:54 周游世界 閱讀(531) 評論(0)  編輯  收藏 所屬分類: JSF 、翻譯
    主站蜘蛛池模板: 亚洲黄色在线电影| 亚洲中文字幕在线观看| 亚洲精品在线网站| 欧洲精品99毛片免费高清观看| 国产精一品亚洲二区在线播放| 精品多毛少妇人妻AV免费久久| 亚洲精品白浆高清久久久久久| 色www永久免费网站| 亚洲a一级免费视频| 久久青草精品38国产免费| 91亚洲精品视频| 无人在线观看免费高清视频| 亚洲精品无码av中文字幕| 欧洲美熟女乱又伦免费视频| 国产精品亚洲专区无码不卡| 亚洲精品岛国片在线观看| 国产成人无码区免费内射一片色欲| 亚洲国产精品久久| 中文字幕人成无码免费视频| 日韩精品亚洲专区在线影视| 亚洲综合色在线观看亚洲| 免费视频成人手机在线观看网址| 亚洲成a人片在线观看中文!!!| 性一交一乱一视频免费看| 一区二区三区在线免费| 亚洲视屏在线观看| 国产精品二区三区免费播放心| 美女巨胸喷奶水视频www免费| 亚洲网红精品大秀在线观看| 日本一道高清不卡免费| 成人免费ā片在线观看| 亚洲人成777在线播放| 亚洲国产成人精品91久久久 | 好看的亚洲黄色经典| 在线观看免费中文视频| 亚洲AV日韩AV永久无码色欲| 亚洲中久无码永久在线观看同 | 日本一区二区三区日本免费| 国产色爽免费无码视频| 亚洲精品无码成人片久久不卡| 国产AV无码专区亚洲AV毛网站|