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

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

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

    隨筆-57  評論-117  文章-1  trackbacks-0

    Struts 概述

    隨著MVC 模式的廣泛使用,催生了MVC 框架的產生。在所有的MVC 框架中,出現最早,應用最廣的就是Struts 框架。

    Struts 的起源

    Struts 是Apache 軟件基金組織Jakarta 項目的一個子項目, Struts 的前身是CraigR. McClanahan 編寫的JSP Model2 架構。

    Struts 在英文中是"支架、支撐"的意思,這表明了Struts 在Web 應用開發中的巨大作用,采用Struts 可以更好地遵循MVC 模式。此外, Struts 提供了一套完備的規范,以基礎類庫,可以充分利用JSP/Servlet 的優點,減輕程序員的工作量,具有很強的可擴展性。

    Struts優點

    提高開發效率,減輕了程序員的工作量,降低了重復代碼(降低代碼冗余),文件不再臃腫。

    可以規范軟件開發的行為。ActionForm為我們封裝請求數據

    增加代碼的擴展性、移植性

    提高代碼的可重用性、可讀性,無需多個Servlet多個方法

    Action轉發頁面只須配置跳轉資源即可,無效全路徑、硬編碼。降低代碼的耦合性

    Struts 架構的工作原理

    1. Model 部分

    Struts 的Model 部分由ActionForm和JavaBean 組成。其中ActionForm用于封裝用戶請求參數,所有的用戶請求參數由系統自動封裝成ActionForm 對象:該對象被ActionServlet轉發給Action; 然后Action 根據ActionForm里的請求參數處理用戶請求。JavaBean 則封裝了底層的業務邏輯,包括數據庫訪問等。在更復雜的應用中,JavaBean所代表的絕非一個簡單的JavaBean,可能是EJB 組件或者其他的業務邏輯組件。該Model 對應圖3 .4的Model 部分。

    2. View 部分

    Struts 的View 部分采用JSP 實現。Struts 提供了豐富的標簽庫,通過這些標簽庫可以最大限度地減少腳本的使用。這些自定義的標簽庫可以實現與Model 的有效交互,并增加了顯示功能。對應圖的JSP 部分。

    整個應用由客戶端請求驅動,當客戶端請求被ActionServlet 攔截時, ActionServlet根據請求決定是否需要調用Model 處理用戶請求,當用戶請求處理完成后,其處理結果通過JSP 呈現給用戶。

    3. Controller部分

    Struts 的Controller 由兩個部分組成。

    ·系統核心控制器—攔截用戶請求ActionServlet 派發請求

    ·業務邏輯控制器—處理用戶請求的Action,處理業務邏輯

    其中,系統核心控制器是一個ActionServlet。該控制器由Struts 框架提供,繼承HttpServlet類,因此可以配置成一個標準的Servlet。該控制器負責攔截所有Http請求,然后根據用戶請求決定是否需要調用業務邏輯控制器,如果需要調用業務邏輯控制器,則將請求轉發給Action 處理,否則直接轉向請求的JSP 頁面。業務邏輯控制器負責處理用戶請求,但業務邏輯控制器本身并不具有處理能力,而是調用Model 來完成處理。業務邏輯控制器對應圖3 .4中的Action 部分。

    clip_image002

    下面結合圖3.7 對Struts 的工作流程作詳細的講解。

    Web 應用都是請求一響應的程序結構。程序是由客戶端Client 發出Http 請求開始的,客戶端請求被ActionServlet 攔截。在ActionServlet 處,有兩種情況:

    ·要求邏輯控制器處理的請求:

    ·簡單轉發的請求。

    對于第一種的請求,ActionServlet 需要調用對應的Action。因此ActionServlet 將請求轉發到Action ,如果請求還配置了對應的FormBean,則ActionServlet 還負責用請求參數填充ActionForm,此時如果ActionForm還沒有創建。ActionServlet會幫我們創建一個可以用的ActionForm,如果ActionForm已經創建就直接給我們用, ActionForm 的實質就是JavaBean,專門用于封裝請求參數。并且在次期間,如果ActionForm如果有驗證方法,會去執行驗證方法,如果驗證通過會進入Action中。驗證失敗,會跳轉到Action配置的input資源頁面。

    此時的Action 將無須從HTTP Request 中獲取請求參數,而是從ActionForm 中獲得請求參數。Action 獲得請求參數后,調用Model 對象由JavaBean 處理用戶請求。Action處理完用戶請求之后,將處理結果包裝成ActionForward,回送給ActionServlet。

    由于ActionForward 對象封裝了JSP 資源的映射。因此, ActionServlet 知道調用合適的JSP 資源表現給客戶端。

    對于第二種請求, HTTP 請求無須Action 處理,只是對普通資源的請求,作為超級鏈接的替代。因為ActionServlet 直接將該請求轉發給JSP 資源,既不會填充ActionForm,也無須調用Action 處理。

    JSP 頁面在表現之前,還需要調用對應的JavaBean,此處的JavaBean 不再是包含業務邏輯的JavaBean,而是封裝了處理結果的普通vo (值對象)。JSP 頁面根據vo 的值,可能利用JSTL 或者Struts 的標簽庫來生成HTTP 響應給客戶端。總之JSP 應盡量避免使用Java 腳本。

    Action配置

    path是我們請求訪問的路徑,如果用struts標簽,會默認加上.do的后綴。ActionServlet攔截到*.do的請求后,就進行相應的業務處理,然后派發到path對應的Action;

    name是Action對象的ActionForm,ActionForm是封裝請求的信息,如表單

    attribute和name一樣,可以省略,在省略的情況下用name。都是對應ActionForm

    type是Action對象對應的文件路徑,含包名

    scope是ActionForm的作用域,默認request

    parameter后帶方法名稱,即請求所執行的方法

    forward是轉發后的資源頁面

    ActionForward配置

    name邏輯名稱和Action中的mapping.forward參數對應

    path對應映射的JSP頁面

    redirect是否重定向請求

    forward有全局和局部的2種,如果當前Action配置的forward資源在當前配置的Action中沒有找到,然后回到全局的forward資源中查找。局部優先全局

    ActonForm配置

    name是form的名稱

    type是form的包名+文件名

    ActionForm還有動態ActionForm、驗證ActionForm

    國際化I18N(Internationalization

    目的:是適應更多的、更好的用戶界面

    Java 程序的國際化主要通過如下三個類完成。

       java.util. ResourceBundle: 對應用于加載一個資源包。

       java.util.Locale: 對應一個特定的國家/區域及語言環境。

       java.text.MessageFormat: 用于將消息格式化。

    為了實現程序的國際化,必須先提供程序所需要的資源文件。資源文件的內容是和很多key-value 對。其中key 是程序使用的部分,而value 則是程序界面的顯示。

    資源文件的命名可以有如下三種形式。

       baseName _language_country.properties。

       baseName _language.properties。

       baseNarne.properties 。

    其中baseName 是資源文件的基本名,用戶可以自由定義。而language 和count可都不可隨意變化,必須是Java 所支持的語言和國家。

    1.國際化支持的語言和國家

    事實上, Java 也不可能支持所有國家和語言,如需要獲取Java 所支持的語言和國家,可調用Locale 類的getAvailableLocale 方法來獲取。該方法返回一個Locale 數組,該數組里包含了Java 所支持的語言和國家。

    2. 編寫國際化所需的資源

    國際化所需的資源文件內容是key-value 對,下面提供了兩個資源文件,這兩個資源文件很簡單,只包含一個key-value 對。

    下面是MyResource.properties 的文件的內容:

    資源文件的內容: key-value 對。

    msg=Hello , {O} Today is {1}.

    下面是MyResource_zh_CN.properties 文件的內容:

    資源文件的內容: key-value 對

    msg=你好. {O} 今天是{l}。

    所有資源文件的key 都是相同的,只是value 會隨國家和語言的不同而變化。

    3.程序從哪里獲取資源呢?

    在ResourceBundle 加載資源時按如下順序搜索。

    搜索所有國家和語言都匹配的資源文件,例如,對于簡體中文的環境,先搜索如下文件:

    MyResource_zh_CN.properties

    如果沒有找到國家和語言都匹配的資源文件,則再搜索語言匹配的文件,即搜索如下文件:

    MyResource_zh.properties

    如果上面的文件依然無法搜索到,則搜索baseNarne 匹配的文件,即搜索如下文件:

    MyResource.properties

    4. 使用類文件代替資源文件

    Java 也允許使用類文件代替資源文件,即將所有的key-value對存入class 文件,而不是屬性文件。

    用來代替資源文件的Java 文件必須滿足如下條件。

    ·類的名字必須為baseNarne_language_country,這與屬性文件的命名相似。

    ·該類必須繼承ListResourceBundle,并重寫getContents 方法,該方法返回Object數組,該數組的每一個項都是key=value 對。

    eg:下面的類文件可以代替上面的屬性文件:

    public class MyResource_zh_CN extends ListResourceBundle {

        // 定義資源

        private final Object myData[][] = { "msg" , " {0}您好!今天是{l} "};

        //重寫方法getContents()

        public Object[] [] getContents() {

            //該方法返回資源的key-value對

            return myData;

        }

    }

    如果系統同時存在資源文件及類文件,則系統將以類文件為主,而不會調用資源文件。對于簡體中文的Locale, ResourceBundle 搜索資源的順序是:

    (1) baseName zh CN.class 。

    (2) baseNarne_zh_CN.properties。

    (3) baseNarne zh.class 。

    (4) baseNarne_zh.properties。

    (5) baseNarne.class。

    (6) baseNarne.properties。

    當系統按上面的順序搜索資源文件時,如果前面的文件不存在,則會使用下一個:如果一直找不到對應的文件,系統將拋出異常。

    struts加載資源文件

    資源文件的加載通過struts-config.xml文件來配置,加載資源文件應從Web 應用的WEB-INF/classes路徑開始加載。因此,資源文件必須放在WEB-INF/classes路徑或該路徑的子路徑下。如果直接放在WEB-INF/classes 路徑下,在配置資源文件時,直接指定資源文件的baseName 即可。但如果放在子路徑下,則必須以包的形式配置。

    動態ActionForm

    Why當一個form表單的屬性、字段非常多的情況下,需要我們不斷的修改、添加ActionForm中的屬性,并提供getter、setter方法。雖然這個類比較簡單,但是大量重復的getter、setter方法也是比較繁瑣的。這個時候struts的動態ActionForm就派上用場了。使用動態ActionForm 的目的是為了減少代碼的書寫量,但是相對在配置方面要復雜些。

    配置動態ActionForm

    所有的動態ActionForm 的實現類都必須是org.apache.struts.action.DynaActionForm類,或者是它的子類。使用動態ActionForm 與前面不同的是:因為系統不清楚動態ActionForm 的屬性,所以必須在配置文件中配置對應的屬性。可以使用form-property 元素來配置動態ActionForm 的屬性。

    <!一配置動態ActionForm,動態Aciton 必須使用烏rnaActionForm 一〉

    <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">

         <!一配置ActionForm的屬性: username-->

         <form-property name="username" type="java.lang.String"/>

         <! 配置ActionForm的屬性: pass-->

         <form-property name="pass"type="java.lang.String"/>

    </form-bean>

     

    <!-- 配置Action中的path , type , name 屬性>

    <action path="/login" type="com.hoo.LoginAction" name="loginForm">

         <!一配置兩個局部Forward-->

         <forward name="welcome" path="/WEB-INF/jsp/welcome.jsp"/>

         <forward name="input" path="/login.jsp"/>

    </action>

    從上面的配置文件可看出,動態ActionForm 的配置必須增加form-property 元素,每個屬性必須對應一個form-property元素。

    form-property元素包含兩個屬性。

    name: 屬性的名字,必須與JSP 頁面的表單域的名字相同。

    type: 屬性的類型。

     

    使用動態ActionForm

    //必須重寫該核心方法,該方法actionForm 將表單的請求參數封裝成值對象

    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

         //將ActionForm強制類型轉換為DynaActionForm

         DynaActionForm loginForm = (DynaActionForm)form;

         //從ActionForm中解析出請求參數: username

         String username = (String)loginForm.get("username");

         //從ActionForm中解析出請求參數: password

         String pass = (String)loginForm.get("pass");

         //后面的處理與前一個示例的Action 相同。

         …………

    }

    使用動態ActionForm 時,請求參數必須使用DynaActionForm的getter 方法獲取。

    DynaActionForm 的getter 方法主要有如下三個。

    Object get(java.lang.String name): 根據屬性名返回對應的值。

    Object get(java.lang.String name, int index): 對于有多個重名表單域的情況, Struts將其當成數組處理,此處根據表面域名和索引獲取對應值。

    Object get(java.lang.String name, java.lang.String key): 對于使用Map 屬性的情況,根據屬性名及對應key. 獲取對應的值。

     

    Struts 的標簽庫

    Struts 提供了大量的標簽庫,用于完成表現層的輸出。借助于Struts 的標簽庫,可避免在JSP 中嵌入大量的Java 腳本,從而提高代碼的可讀性。

    Struts 主要提供了如下三個標簽庫。

    A、 html: 用于生成HTML 的基本標簽。

    B、 bean: 用于完成程序國際化,輸出Struts 的ActionForm 的屬性值等。

    C、 logic: 用于完成循環、選擇等流程控制。

     

    使用html 標簽庫

    Struts 為htrnl 的大部分標簽提供了對應的htrnl 標簽, htrnl 所支持的標簽大致有如下。

    * base: 表現成一個HTML 的<base>標簽。

    * button: 表現成一個按鈕,該按鈕默認沒有任何動作。

    * cancel: 表現成一個取消按鈕。

    * checkbox: 表現成一個Checkbox 的輸入框。

    * error: 用于輸出數據校驗的出錯提示。

    * file: 表現成一個文件瀏覽輸入框。

    * form: 表現成一個form 域。

    * frame: 表現成一個HTML<frame>標簽。

    * hidde: 表現成一個隱藏域。

    * htrnl: 表現成HTML 的<htrnl>標簽。

    * image: 表現成表單域的image 域。

    * img: 表現成一個HTML 的img 標簽。

    * javascrit: 表現成JavaScript 的校驗代碼,這些校驗代碼根據ValidatorPlugIn 生成。

    * link: 表現成HTML 的超級鏈接。

    * messages: 用于輸出Struts 的各種提示信息,包括校驗提示。

    * multibox: 表現成一個Checkbox 輸入框。

    * option: 表現成選擇框的一個選項。

    * password: 表現成一個密碼輸入框。

    * radio: 表現成一個單選輸入框。

    * reset: 表現成一個重設按鈕。

    * rewrite: 表現成一個URL 。

    * select: 表現成一個列表選擇框。

    * submit: 表現成一個提交按鈕。

    * text: 表現成一個單行文本輸入框。

    * textarea: 表現成一個多行文本框。

     

    使用bean 標簽庫

    bean 標簽庫主要用于輸出屬性值、提示消息及定義請求參數等。下面是bean 標簽庫的常用標簽。

    * cookie: 將請求的cookie 的值定義成腳本可以訪問的JavaBean 實例。

    * define: 將某個bean 的屬性值定義成腳本可以訪問的變量。

    * header: 將請求頭的值定義成腳本可以訪問的變量。

    * include: 將某個JSP 資源完整定義成一個bean 實例。

    * message: 用于輸出國際化信息。

    * page: 將page Context 中的特定項定義成一個bean 。

    * parameter: 將請求參數定義成腳本可以訪問的變量。

    * resource: 加載Web 應用的資源,并將其變成JavaB eano

    * struts: 用于將某個Struts 的內部配置成一個bean 。

    * write: 用于輸出某個bean 的屬性值。

     

    使用logic 標簽庫

    logic 標簽庫是使用最頻繁,相對復雜的標簽庫。logic 標簽庫主要用于完成基本的流程控制,比如循環及選擇等。

    logic 標簽庫主要有如下標簽。

    * empty: 如果給定的變量為空或者為空字符串,則就計算并輸出標簽體的內容。

    * equal: 如果給定變量與特定的值相等,則會計算并輸出該標簽體的內容。

    * forward: 將某個頁面的控制權forward 確定的ActionForward 項。

    * greaterEqual: 如果給定變量大于或等于特定的值,則會計算并輸出標簽體的內容。

    * greaterThan: 如果給定變量大于特定的值,則會計算井輸出標簽體的內容。

    * iterate: 通過遍歷給定集合的元素,對標簽體的內容進行循環。

    * lessEqual: 如果給定變量小于或等于特定的值,則會計算并輸出標簽體的內容。

    * lessThan: 如果給定變量小于特定的值,則會計算并輸出標簽體的內容。

    * match: 如果特定字符串是給定消息合適的子字符串,則會計算并輸出標簽體的內容。

    * messagesNotPresent: 如果請求中不包含特定的消息內容,將計算并輸出標簽體的內容。

    * messagesPresent: 如果請求中包含特定的消息內容,則計算并輸出標簽體的內容。

    * notEmpty: 如果給定的變量既不為空,也不是空字符串,則計算并輸出標簽體的內容。

    * notEqual: 如果給定變量不等于特定的值,則會計算并輸出標簽體的內容。

    * notMatch: 如果特定宇符串不是給定消息合適的子字符串,則會計算并輸出標簽體的內容。

    * notPresent: 如果特定的值沒有出現在請求中,則計算并輸出標簽體的內容。

    * present: 如果特定的值出現在請求中,則計算并輸出標簽體的內容。

    * redirect: 重定向頁面。

     

    Struts 的數據校驗

    數據校驗也稱為輸入校驗,指導對用戶的輸入進行基本過濾,包括必填宇段,宇段必須為數字及兩次輸入的密碼必須相匹配等。這些是每個MVC 框架都應該完成的任務,Struts 提供了基本的數據校驗,如果結合commons-validator, Struts 則擁有強大的校驗框架,包括進行客戶端的JavaScript 校驗等。

    Struts 的數據校驗大致有如下幾種方式:

    ActionForm 的代碼校驗。

    Action 里的代碼校驗。

    結合commons-validator.jar 的校驗。

     

    ActionForm 的代碼校驗

    ActionForm 的代碼校驗是最基本的校驗方式。這種校驗方式是重寫ActionForm 的validate 方法,在該方法內對所有的宇段進行基本校驗。如果出現不符合要求的輸出,則將出錯提示封裝在ActionError 對象里,最后將多個ActionError 組合成ActionErrors 對象,該對象里封裝了全部的出錯提示。并將錯誤信息用<html:error/>展現在配置的input的失敗頁面上。

     

    Action 的代碼校驗

    在Action 里通過代碼完成輸入校驗,是最基本,也最容易使用的方法。與最初的MVC 設計相似,在調用業務邏輯組件之前,先對數據進行基本校驗。這是最傳統也是最原始的方法。

    這種校驗方式非常容易理解,所有的代碼都需要程序員自己控制,相當靈活。

    但有如下幾個不方便之處。

    ·用戶需要書寫大量的校驗代碼,使程序變得煩瑣。

    · 數據校驗應該在填充ActionForm里完成,最好能在客戶端完成校驗,而不是推遲到Action 里才完成數據校驗。

    注意:在實際的使用中,這種校驗方式不僅程序開發復雜,且性能也不高。

     

    結合commons-validator.jar 的校驗

    借助于commons-validator.jar 的支持, Struts的校驗功能非常強大,幾乎不需書寫任何代碼。不僅可以完成服務器端校驗,同時還可完成客戶端校驗,即彈出Javascript 提示。

    使用commons-validator.jar 校驗框架時,有如下幾個通用配置。

    ·增加校驗資源。

    ·利用ValidatorPlugIn 加載校驗資源。

    ·ActionForm 使用ValidatorForm 的于類。

    下面分別通過三個示例講解這三種校驗:基本的校驗、對動態ActionForm 執行校驗及彈出JavaScript 校驗提示。

     

    1. 繼承ValidatorForm 的校驗

    如果需要使用commons-validator 框架,請按如下步驟進行。

    (1) Struts 的ActionForm必須是ValidatorForm的子類,提供驗證屬性字段的getter、setter方法

    (2) 編寫表單域時必須滿足校驗規則。校驗規則都由規則文件控制,規則文件有以下兩個。

    * validator-rules.xml 文件

    * validation.xml 文件

    第一個文件可在Struts 的解壓縮后的文件夾的lib 下找到,將該文件復制到WEB-INF

    2. common-validator支持的校驗規則

    common-validator支持的校驗規則非常豐富,特別是mask 和validwhen 兩個規則,

    極大地豐富了該校驗框架的功能。

    常用的校驗規則有如下幾種。

    * required: 必填。

    * va1idwhen: 必須滿足某個有效條件。

    * minlength: 輸入必須大于最小長度。

    * maxlength: 輸入必須小于最大長度。

    * mask: 輸入匹配正確的表達式。

    * byte: 輸入只能是一個byte 類型變量。

    * short: 輸入只能是一個short 類型變量。

    * integer: 輸入只能是一個integer 變量。

    * long: 輸入只能是一個long 變量。

    * float: 輸入只能是一個float 變量。

    * double: 輸入只能是一個double 變量。

    * date: 輸入必須是一個日期。

    * intRange: 輸入的數字必須在整數范圍內。

    * floatRange: 輸入的數字必須在單精度浮點數范圍內。

    * doubleRange: 輸入的數字必須在雙精度浮點數范圍內。

    * email: 輸入必須是有效的E-mail 地址。

    * uri: 輸入必須是有效的uri 地址。

    3.使用DynaValidatorForm 的校驗

    即使不書寫ActionForm,也可以利用cornmon-validator 校驗框架。此時使用的ActionForm 的實現類,必須既是動態Form ,也是驗證Form,DynaValidatorForm 就是滿足這兩個條件的Form。

    4. 彈出客戶端JavaScript提示

    如需要彈出客戶端JavaScript 校驗非常簡單,無須修改其他配置文件,只需修改登錄使用的JSP 頁面的兩個地方。

    (1) 為form 元素增加onsubmit="return validateXxxForm(this);"屬性,其中的XxxForm就是需要校驗的form 名,與struts-config.xrnl中配置的form-bean 的name 屬性一致,也與validation.xrnl文件中需要校驗的form 的name 屬性一致。

    (2) 增加<html:javascript formName="xxxForm"/> ,其中xxxForm 是需要校驗的form 名。

    注意:即使使用了客戶端技驗規則,也不要刪除頁面的htm1 :rnessages 標簽。因為該標簽會在客戶端技驗通過,而在服務器端技驗并未通過時彈出提示。

     

    Struts 的異常框架

    Struts 1.1 版本中加入了對異常的處理,稱之為Exception Handling,標志著作為一個整體的框架, Struts 越來越趨于成熟。

    在以前的Struts 開發過程中,對于異常的處理,主要是采用手動處理的方式:如通過try/catch 等捕獲異常:然后將定制個性化的,比較詳細的錯誤信息放進ActionMessage中:最后在返回頁面中把這些錯誤信息反饋給用戶。

    對于異常的原始信息,不管是最終用戶還是開發員都不希望看到。

    借助于Struts 的異常框架,異常處理只需通過struts-config.xm1文件定義即可。根據異常定義的位置不同,異常可分為局部異常和全局異常兩種。

    ·局部異常作為action 的子元素中定義。

    ·全局異常在globa1-excetpions 元素中定義。

    異常定義的格式如下:

    <exception key="keyNarne" type="ExceptionNarne" scope="scope" path="uri"/>: 當Struts 出現ExceptionNarne 的異常時,頁面自動轉向uri 指向的資源,并在該頁面輸出keyName 對應的國際化中的出錯提示。

    幾種常用的Action

    除了基本的Action 之外, Struts 還提供了幾個其他類型的Action ,這些Action 大大豐富了Struts 的功能。下面介紹如下兒個常用的Action 。

    * DispatchAction: 能同時完成多個Action 功能的Action 。

    * ForwardActon: 該類用來整合Struts 和其他業務邏輯組件,通常只對請求作有效性檢查。

    * IncludeAction: 用于引入其他的資源和頁面。

    * LookupDispatchAction: DispatchAction 的子類,根據按鈕的key ,控制轉發給action的方法。

    * MappingDispatchAction: DispatchAction 的子類,一個action 可映射出多個Action地址。

    * SwitchAction: 用于從一個模塊轉換至另一個模塊,如果應用分成多個模塊時,就可以使用SwitchAction 完成模塊之間的切換。

     

    DispatchAction

    在該action 的配置中,增加了parameter屬性,該屬性用于指定參數名,即Struts 將根據該參數的值調用對應的方法。為了讓請求增加method 的參數,method參數對應的是要請求執行的方法。

    <action path="/login" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="method">

         <forward name="success" path="/welcome.jsp"/>

    </action>

    Login.do?method=login

     

    MappingDispatchAction

    可將同一個Action 的不同方法映射成多個Action URI ,這種Action 的寫法與DispatchAction 非常相似,同樣不需要重寫execute 方法,而是將書寫多個自定義的方法。這些方法除了方法名與execute 方法不同外,其他的參數列表及異常處理完全一樣。

    <!-- 配置第一個Action. 實現類是com.hoo.LoginAction , parameter 為add-->

    <action path="/add" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="add">

         <forward name="success" path="/welcome.jsp"/>

    </action>

    <! 配置第二個Action. 實現類是com.hoo.LoginAction , parameter 為modify-->

    <action path="/modify" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="modify">

         <forward name="success" path="/welcome.jsp"/>

    </action>

    其中,path對應的是請求的地址uri,而parameter是對于當前請求所執行的方法;

    注意:使用MappingDispatchAction 并沒有帶來太大的優勢,系統完全可以書寫兩個Action,分別定義兩個不同的action 映射,而其他部分沒有區別。

    LookupDispatchAction

    LookupDispatchAction也是DispatchAction 的一種,但它的處理更加簡單。該Action也可包含多個處理方法,它可讓處理方法與按鈕直接關聯,無須使用任何的JavaScript腳本。因此可通過重寫getKeyMethodMap方法完成按鈕與Action 中方法的關聯。

    //用于關聯按鈕和方法

    protected Map getKeyMethodMap() {

         Map map = new HashMap();

         //如果按鈕標題的key 為button.add. 則提交該按鈕時對應add 方法

         map .put ("button. add" , "add");

         //如果按鈕標題的key 為button.modify. 則提交該按鈕時對應modify 方法

         map.put ("button.modify" , "modify") ;

         return map;

    }

     

    ForwardAction

    如果需要從一個頁面或資源轉換到另一個資源時,直接使用頁面或資源路徑的超級鏈接定位并不是好的做法,這使得控制器沒有機會處理相關的請求事直。

    使用ForwardAction可以完成請求的轉發,當控制器調用ForwardAction的perform()方法時,它會使用屬性parameter 所設定的路徑進行forward 的動作。下面是一個設定ForwardAction的例子:

    <actlon-mapplngs>

         <action path="/welcome" type="org.apache.struts.actions.ForwardAction" parameter="/welcome.jsp"/>

    </action-mappings>

    該action 僅僅完成轉發,并沒有執行其他的額外動作。頁面控制轉發的代碼如下:

    <a href="welcome.do">轉入</a>

    當單擊轉入超級鏈接時,將可以轉向ForwardAction中parameter指向的資源。

     

    IncludeAction

    IncludeAction的用法與ForwardAction的用法比較相似,區別在于ForwardAction將跳轉到action 定義的資源,而IncludeAction用于引入該action 對應的資源。

    下面是IncludeAction定義的源代碼:

    <action-mapplngs>

         <action path="/welcome" type="org.apache. struts.actions.IncludeAction" parameter="/welcome.jsp"/>

    </action-mappings>

    該action 用于經welcome.jsp 作為資源導入。

    頁面中負責加載該action 所導入資源的代碼如下:

    <jsp:include page="welcome.do"/><br>

    上面的代碼將會把welcome action 定義的資源導入該頁面。

     

    SwitchAction

    SwitchAction 主要用于模塊之間的切換。當一個應用之中存在多個模塊時,使用SwitchAction在不同模塊之間的action 之間切換還是相當方便的。

     

    Struts 的常見擴展方法

    Struts 的強大吸引力還來自于它的可擴展性,其擴展性通常有如下三種方式。

    ·實現PlugIn: 如果需要在應用啟動或關閉時完成某些操作,可以創建自己的PlugIn類。

    ·繼承RequestProcessor: 如果想在請求被處理中的某個時刻做一些業務邏輯時,可以考慮實現自己的RequestProcessor 類。

    ·繼承ActionServlet: 如果需要在每次開始處理請求之前,或者處理請求結束之后完成某些操作,可以實現自己的ActionServlet 來完成擴展。

     

    下面分別從三個方面來介紹Struts 的擴展。

    實現PlugIn 接口

    Struts 已經演示了PlugIn 的擴展方法:與common- validation 的整合。后面還將介紹Spring 與Struts 的整合,也利用了PlugIn 的擴展。

    在下面的應用中,系統使用Hibernate 作為持久層,在啟動時創建SessionFactory 實例,并將該SessionFactory 存入application ,在應用關閉時銷毀SessionFactory 。只需如下兩步即可完成此功能。

    (1) 實現自己的PlugIn 類。

         實現PlugIn 接口必須實現如下兩個方法。

         1 void destroy()。

         2 void init(ActionServlet serlet, ModuleConfig config) 。

         應用啟動時調用init 方法,而應用關閉時則調用destroy 方法。

         下面是SessionFactoryLoaderPlugIn 的實現類:

         public class SessionFactoryLoaderPlugin implements PlugIn {

              //Hibernate 的配置文件

              private String configFile;

              //應用關閉時,銷毀資源

              public void destroy()

                   System.out.println("系統銷毀SessionFactory");

              }

              //應用啟動時,完成SessionFactory 的初始化

              public void init(ActionServlet actionServlet , ModuleConfig config) throws ServletException

                   System.out.println("系統以" + getConfigFile() + "為配置文件初始化SessionFactory") ;

                  //獲取Plugln 配置文件的方法

                   public String getConfigFile() {

                        return configFile;

                   }

              // 負責加載Plugln 配置屬性的方法

              public void setConfigFile(String configFile) {

                    this.configFile = configFile;

              }

         }

    在上面的PlugIn 中,并沒有真正初始化SessionFactory ,僅在控制臺打印出字符串來標識創建動作。另外,還提供了configFile 屬性的setter 和getter 方法,這兩個方法負責訪問plugin 元素的configFile 屬性。

     

    ( 2 ) 將SessionFactoryLoaderPlugIn 配置在struts-config.xml 文件中。方法與ValidatorPlugIn 的配置并沒有區別,下面是配置SessionFactoryLoaderPlugIn 的代碼:

    <plug-in className="hoo.SessionFactoryLoaderPluging">

         <set-property property="conf工gFile" value=" WEB-INF/hibernate.cfg.xml"I>

    </plug-in>

    在配置SessionFactoryLoaderPlugIn 時,配置了configFile 屬性,該屬性用于確定Hibernate 配置文件的文件名。

     

    繼承RequestProcessor

    RequestProcessor 是Struts 的核心類,而Struts 的核心控制器是ActionServlet 。但ActionServlet 并未完成真正的處理,只是調用RequestProcessor , RequestProcessor 才是Struts 的核心類。

    擴展RequestProcessor 的實例在Spring 中有個示范, Spring 提供的Delegating RequestProcessor 是一個很好的示例。下面示例對RequestProcessor 進行簡單的擴展。

    RequestProcessor 包含了如下常見的方法。

    * ActionForm processActionForm: RequestProcessor填充ActionForm 時執行該方法。

    * Action processActionCreate: RequestProcessor 調用Action 時調用該方法。

    * boolean processPreprocess: 預處理用戶請求時執行該方法。

    * boolean processValidate: 處理輸入校驗時調用該方法。

    擴展RequestProcessor 只需兩步即可。

    (2)在struts-config.xml 文件中配置MyRequestProcessor。用戶重寫了RequestProcessor,但Struts 并不知道,必須在struts-config且nl 中配置才可以。

    下面是配置MyRequestProcessor 的代碼:

    <controller processorClass="lee.MyRequestProcessor" />

    該屬性的配置應該放在action-mappings元素之后。

    注意:重寫RequestProccessor的方法時,別忘了使用super 來調用父類的動作。如果沒有調用該方法,意味著開發者必須完成Struts 框架所完成的動作。這是不應該的,因為程序員只是在框架中加入額外的處理,并不是要替代Struts。

     

    繼承ActionServlet

    如果需要在開始處理請求,或者處理結束之后加入自己的處理時,可對ActionServlet進行擴展。例如解決中文的編碼問題。

    ActionServlet 接收處理請求參數時,并不是按GBK 的解碼方式處理請求,因此容易形成亂碼。為了解決該問題,可以強制指定ActionServlet 使用GBK 的解碼方式。

    繼承ActionServlet重寫process方法,設置request、response編碼為gbk,然后配置在web.xml中。



    作者:hoojo
    出處:
    blog:http://blog.csdn.net/IBM_hoojo
             http://hoojo.cnblogs.com
    本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


    版權所有,轉載請注明出處 本文出自:
    分享道版權所有,歡迎轉載,轉載請注明出處,謝謝
    posted on 2012-01-29 16:48 hoojo 閱讀(1940) 評論(4)  編輯  收藏 所屬分類: JavaEEStruts

    評論:
    # re: Struts 筆記 2012-01-30 10:54 | tb
    不錯 謝謝分享了   回復  更多評論
      
    # re: Struts 筆記 2012-02-01 14:04 | 楊Coder
    總結得相當全面啊!  回復  更多評論
      
    # re: Struts 筆記 2012-02-01 16:23 | hoojo
    @楊Coder
    謝謝支持  回復  更多評論
      
    # re: Struts 筆記 2012-02-03 23:37 | allenny
    你這不是1.0版本的Struts嘛  回復  更多評論
      
    主站蜘蛛池模板: 亚洲成综合人影院在院播放| 特级毛片全部免费播放a一级| 欧洲黑大粗无码免费| 亚洲女子高潮不断爆白浆| 亚洲日本在线观看视频| 外国成人网在线观看免费视频| 亚洲AV无码无限在线观看不卡| 亚洲偷自拍拍综合网| 日本免费网站视频www区| 色妞www精品视频免费看| 亚洲午夜久久久精品影院| 国产免费人成视频在线观看| 国产在线观看免费视频软件| 亚洲人成网站色在线观看| 国产AV无码专区亚洲AWWW | 免费观看激色视频网站(性色)| 亚洲欧美国产精品专区久久| 亚洲国产精品无码专区在线观看| 成人激情免费视频| 99久久国产精品免费一区二区 | 最近中文字幕完整免费视频ww | 男男AV纯肉无码免费播放无码| 男女一边桶一边摸一边脱视频免费| 亚洲an日韩专区在线| 国产亚洲AV夜间福利香蕉149| 最近最好的中文字幕2019免费| 国产午夜无码精品免费看| 噜噜噜亚洲色成人网站| 亚洲人成网网址在线看| 亚洲成a人片77777kkkk| jjzz亚洲亚洲女人| 成年女人午夜毛片免费看| 99久久国产免费-99久久国产免费 99久久国产免费中文无字幕 | 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 亚洲一区精品伊人久久伊人| 在线观看视频免费完整版| 99re免费视频| 99热在线日韩精品免费| 色婷婷综合缴情综免费观看 | 美美女高清毛片视频黄的一免费| 亚洲欧洲校园自拍都市|