JSF和MVC

JSF和MVC
1.    JSF 和 MVC
JSF 是幾年前學過的在 Java 平臺上改進 Web 開發技術的課程的結果。這一趨勢開始於 JSP 技術,這一技術很好,只是很容易在 HTML(和類 HTML)頁面中混合 Java 代碼。下一次提高是 Model 1 架構,它讓開發人員將大多數後端代碼放入 JavaBeans 組件中,然後用 <jsp:useBean> 標籤將 JavaBeans 組件導入 Web 頁面。這對於簡單的 Web 應用程序工作得很好,但是許多 Java 開發人員不喜歡 JSP 技術這種與 C++ 特性(比如靜態包含)的協作。所以引入了 Model 2 架構。
本質上,Model 2 架構是用於 Web 應用程序的 MVC 的打了折扣的版本。在 Model 2 架構中,控制器是由 Servlets 來表示的,而顯示則委派給 JSP 頁面。Struts 是一種簡化的 Model 2 實現,其中的 Actions 代替了 Servlets。在 Struts 中,應用程序的控制器邏輯是與它的數據(由 ActionForms 表示)相分離的。對於 Struts 的主要抱怨是,它感覺上更像過程化的,而不像面向對象的。WebWork 和 Spring MVC 是另外兩個 Model 2 架構,它們更加不像過程化的,在 Struts 的基礎上有所改進,但是它們仍然沒有 Struts 那樣被廣泛接受(或者沒有那麼成熟,有人可能對此有爭議)。並且也不提供像 JSF 提供的那些組件模型。
關於大多數 Model 2 框架的實際問題是,事件模型太簡單了(本質上是一個非常縮小的 MVC),這就給開發人員留下了太多的工作。更豐富的事件模型使得創建大多數用戶期望的交互更加容易。像 JSP 技術一樣,大多數 Model 2 也很容易利用 GUI 自定義標籤來混合 HTML 佈局和格式化,這些標籤有點類似於組件。而有些 Model 架構(比如 Struts)出現分離行爲與狀態的錯誤,這讓許多 Java 開發人員感覺自己是在進行 COBOL 編程。
2.    更豐富的 MVC 環境
       JSF 提供一個組件模型和一個比大多數 Model 2 實現更豐富的 MVC 環境。本質上,JSF 比 Model 2 架構更加接近於真正的 MVC 編程環境,儘管它仍然是一種無狀態的協議。JSF 也比 Model 2 架構更方便構建更加細緻的事件驅動 GUI。儘管 JSF 給了您很多事件選項(菜單項選擇、按鈕單擊,等等),但是大多數 Model 2 依賴於更加簡單的“請求接受”。
       JSF 的良好調優的事件模型,允許您的應用程序與 HTTP 細節的聯繫更少,並簡化了開發。通過使得更加容易將表示和業務邏輯移出控制器,以及將業務邏輯移出 JSP 頁面,JSF 也在傳統的 Model 2 架構上有了一些改進。事實上,簡單的控制器類根本與 JSF 沒有聯繫,這使得它們更加容易測試。與真正的 MVC 架構不一樣,JSF 模型層不可能發出許多必須在多個視窗(viewport)中解決的事件;此外,我們仍然在處理無狀態的協議,所以這是沒必要的。用於更改或更新視圖的系統事件幾乎總是用戶請求。
3.    JSF 的 MVC 實現細節
       JSF MVC 實現中,mapping backing beans(映射支持 beans)在視圖和模型之間調停。因此,限制 backing beans 中的業務邏輯和持久性邏輯很重要。一個常見的替代方法是,將業務邏輯委派給應用程序模型。在這種情況下,backing beans 也映射模型對象,其中視圖可以顯示它們。另一種選項是,將業務邏輯放在 Business 代表中,後者充當模型。
       與 JSP 技術不一樣,JSF 的視圖實現是一個有狀態的組件模型。JSF 視圖包含兩個部分:視圖根和 JSP 頁面。視圖根是 UI 組件集合,這些組件維護 UI 的狀態。與 Swing 和 AWT 一樣,JSF 組件使用 Composite 設計模式來管理組件樹(簡單地說,容器包含組件,容器也是一個組件)。JSP 頁面將 UI 組件綁定到 JSP 頁面,並允許您將字段組件綁定到 backing beans 的屬性(或者屬性的屬性),以及將按鈕綁定到事件處理器和操作方法。
 
下面是一個從 MVC 角度來看的示例應用程序。
4.    示例應用程序:
1.     問題描述:該例是一個簡單的 計算器 應用程序。
       創建該應用程序的目標是向終端用戶呈現一個頁面,讓他/她輸入兩個數值。因此,該頁面具有兩個文本字段、兩個標籤、兩個錯誤消息位置和一個 Submit 按鈕。文本字段用於輸入數值。標籤用於標註字段。錯誤消息位置用於顯示針對文本字段的驗證或數據轉換錯誤消息。
2.     分析:
       1) 視圖:存在二個 JSP 頁面:
       calculator.jsp,它呈現前面提到的 GUI;
       results.jsp,它顯示結果。
2) 控制器(充當從模型到視圖的粘合劑):一個叫做 CalculatorController 的託管 bean 充當 calculator.jsp 和 results.jsp 的 backing bean。
    3) 模型:Calculator類,負責實現兩個數的加、減、乘、除的業務邏輯。
3.     示例應用程序的MVC 視圖:
4.     構建應用程序:
       1) 創建名爲calculatorApp的web應用程序:並配置好JSF環境
       2) 創建業務邏輯類:Calculator.java
package org.qiujy.service;
 
 
/**
 *計算器業務邏輯類
 *@authorAdministrator
 */
publicclass Calculator {
   
    /**
     *加法運算
     *@paramafirstNumber
     *@parambsecondNumber
     *@returnresult
     */
    publicdouble add(double a, double b){
        return a + b;
    }
    /**
     *減法運算
     *@parama
     *@paramb
     *@return
     */
    publicdouble subtract(double a, double b){
        return a - b;
    }
    /**
     *乘法運算
     *@parama
     *@paramb
     *@return
     */
    publicdouble multiply(double a, double b){
        return a * b;
    }
    /**
     *除法運算
     *@parama
     *@paramb
     *@return
     */
    publicdouble divide(double a, double b){
        return a / b;
    }
}
       3) 創建控制器(受管Bean)來粘接模型和視圖:CalculatorController.java。
       控制器的目標是充當從模型到視圖的粘合劑。Controller 對象的其中一個功能是保持模型對於視圖技術不可知。正如從下面可以看到的,控制器指定三個 JavaBeans 屬性,這些屬性將用於收集輸入和顯示結果。這三個屬性是:results(輸出)、firstNumber(輸入)和 secondNumber(輸入)。Controller 也呈現四個操作,它們委派給 Calculator 對象中相同名稱的操作。
      
package org.qiujy.controller;
 
import org.qiujy.service.Calculator;
 
/**
 *受管Bean
 *
 *@authorAdministrator
 *
 */
publicclass CalculatorController {
    /** Representthemodelobject.*/
    private Calculator calculator = new Calculator();
    /**Firstnumberusedinoperation.*/
    privatedoublefirstNumber = 0;
    /**Resultofoperationonfirstnumberandsecondnumber.*/
    privatedoubleresult = 0;
    /**Secondnumberusedinoperation.*/
    privatedoublesecondNumber = 0;
 
    public Calculator getCalculator() {
        returncalculator;
    }
 
    publicvoid setCalculator(Calculator calculator) {
        this.calculator = calculator;
    }
 
    publicdouble getFirstNumber() {
        returnfirstNumber;
    }
 
    publicvoid setFirstNumber(double firstNumber) {
        this.firstNumber = firstNumber;
    }
 
    publicdouble getResult() {
        returnresult;
    }
 
    publicvoid setResult(double result) {
        this.result = result;
    }
 
    publicdouble getSecondNumber() {
        returnsecondNumber;
    }
 
    publicvoid setSecondNumber(double secondNumber) {
        this.secondNumber = secondNumber;
    }
 
    /**
     *Addsthefirstnumberandsecondnumbertogether.
     *@returnnextlogicaloutcome.
     */
    public String add() {
        result = calculator.add(firstNumber, secondNumber);
        return"success";
    }
 
    public String subtract() {
        result = calculator.subtract(firstNumber, secondNumber);
        return"success";
    }
 
    /**
     *Multipliesthefirstnumberandsecondnumbertogether.
     *@returnnextlogicaloutcome.
     */
    public String multiply() {
        result = calculator.multiply(firstNumber, secondNumber);
        return"success";
    }
 
    public String divide() {
        result = calculator.divide(firstNumber, secondNumber);
        return"success";
    }
}
       4) 在faces-config.xml文件中聲明受管Bean和導航規則:
<managed-bean>
    <managed-bean-name>CalcBean</managed-bean-name>
    <managed-bean-class>
        org.qiujy.controller.CalculatorController
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>
       上面的配置告訴 JSF,您想要將一個 受管bean 添加到叫做 CalcBean 的 JSF 上下文。您可以向自己的受管 bean 調用任何事情。
      
<navigation-rule>
    <from-view-id>/calculator.jsp</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/result.jsp</to-view-id>
    </navigation-case>
</navigation-rule>
       上面的導航規則指出,如果一個操作從 /calculator.jsp 視圖返回邏輯結果“success”,那麼就會將用戶轉向 /results.jsp 視圖。
       5) 創建calculator.jsp和result.jsp:
<%@ page language="java" pageEncoding="GBK"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
 
<html>
         <head>
                   <title>My JSF 'calculator.jsp' starting page</title>
         </head>
 
         <body>
                   <f:view>
                            <h:form id="calcForm">
                                     <h:panelGrid columns="3">
                                               <h:outputLabel value="第一個數" for="firstNumber" />
                                               <h:inputText id="firstNumber" value="#{CalcBean.firstNumber}"
                                                        required="true" />
                                               <h:message for="firstNumber" />
                                               <h:outputLabel value="第二個數" for="secondNumber" />
                                               <h:inputText id="secondNumber" value="#{CalcBean.secondNumber}"
                                                        required="true" />
                                               <h:message for="secondNumber" />
                                     </h:panelGrid>
                                     <h:panelGroup>
                                               <h:commandButton id="submitAdd" action="#{CalcBean.add}"
                                                        value="" />
                                               <h:commandButton id="submitSubtract" action="#{CalcBean.subtract}"
                                                        value="" />
                                               <h:commandButton id="submitMultiply" action="#{CalcBean.multiply}"
                                                        value="" />
                                               <h:commandButton id="submitDivide" action="#{CalcBean.divide}"
                                                        value="" />
                                     </h:panelGroup>
 
                            </h:form>
                   </f:view>
         </body>
</html>
       命令按鈕使用 action="#{CalcBean.add}" 將按鈕綁定到 backing bean 上的一個方法。因此,當用按鈕提交表單時,關聯的方法就會被調用。
<%@ page language="java" pageEncoding="GBK"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
 
<html>
         <head>
                   <title>My JSF 'calculator.jsp' starting page</title>
         </head>
 
         <body>
                   <f:view>
                   第一個數: <h:outputText id="firstNumber" value="#{CalcBean.firstNumber}" />
                            <br />
                第二個數: <h:outputText id="secondNumber" value="#{CalcBean.secondNumber}" />
                            <br />
                結果: <h:outputText id="result" value="#{CalcBean.result}" />
                            <br />
                   </f:view>
         </body>
</html>
 
       6) 部署,調試:
 
源碼:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章