Struts配置詳解


一、Stuts的元素

1 web.xml

       任何一個web應用程序都是基於請求響應模式進行構建的,所以無論采用哪種MVC框架,都離不開web.xml文件的配置.換句話說,web.xml並不是Struts2框架特有的文件,只有在Web應用中配置了web.xml文件,MVC框架才能真正地與Web應用融合起來.因此,web.xml文件是所有JavaWeb應用程序都需要的核心文件.

       Struts2框架需要在web.xml中配置其核心控制器—StrutsPrepareAndExecuteFilter,用於對框架進行初始化,以及處理所有的請求.

  StrutsPrepareAndExecuteFilter可以包含一些初始化參數,經常使用的如config——要加載的XML形式的配置文件列表(多個配置文件以逗號分隔,) 如果沒有設置這個參數,Struts2框架將默認加載struts-default.xml,struts-plugin.xml和struts.xml.

       StrutsPrepareAndExecuteFilter作為一個Filter在Web應用中運行,它負責攔截所有的用戶請求,當用戶請求到達時,該Filter會過濾用戶請求.如果用戶請求以action結尾,該請求將被傳遞到Struts2框架進行處理.

2 Action

      實際上,在MVC框架中,控制器是由兩個部分組成,分別如下:

  • 核心過濾器(Filter):用於攔截用戶請求,對請求進行處理
  • 業務控制器(Action):調用相應的Model類實現業務處理,返回結果.

       對於開發人員來說,使用Struts2框架,主要的編碼工作就是編寫Action類,而自定義的Action需要實現com.opensymphony.xwork2.Action接口和繼承com.opensymphony.xwork2.ActionSupport類,Struts2並不要求編寫的Action類一定要實現Action接口,可以編寫一個普通的Java類作為Action類,只要該類含有一個返回字符串的無參的public方法即可.

       在實際開發中,Action類通常都繼承自Struts2提供的com.opensymphony.xwork2.ActionSupport類,以便簡化開發.

3 Result

       result元素的作用是實現結果視圖的調用,並決定視圖以哪種形式展現給客戶端.簡單地說,就是用來設定在Action處理結束后,系統下一步將要做什么.

       Action類在處理完用戶操作后,會返回一個處理結果.這個結果是一個簡單字符串,框架根據這個字符串選擇對應的Result,所以我們又將其稱為邏輯視圖名稱.這個邏輯視圖名由result元素的name屬性來表示.result元素的值用來指定這個邏輯視圖對應的物理視圖資源的位置.需要特別指出的是,邏輯視圖名稱只有與物理視圖資源聯系在一起,才能發揮作用,所以必須要在配置文件中設置二者之間的對應關系.

       通過對Struts2執行過程的分析,可以發現Struts2應用的整個過程都是按照請求/響應的過程執行的,如下圖:

1)     當Web服務器接收到請求之后,將請求交由web.xml中配置的struts2框架的核心過濾器StrutsPrepareAndExecuteFilter.

2)     由StrutsPrepareAndExecuteFilter確定請求對應的Action(業務控制器)

3)     框架根據Action返回的結果字符串,由StrutsPrepareAndExecuteFilter選擇對應的result,將結果呈現給用戶.

二、 Struts2的配置文件 struts.xml

1.  constant元素

        constant元素用於配置常量,通過常量的配置,可以改變Struts2框架的一些行為,從而滿足不同應用的需求.constant元素包含兩個屬性:其中name屬性表示常量的名稱,value表示常量的值.例如:

<constant name="struts.configuration.xml.reload" value="true" />

 

Struts2默認的常量配置在default.properties文件中,我們可以在struts.xml文件中進行修改:

常用的常量配置:

<!-- 常用的常量設置 -->
    <!--指定默認編碼,作用於HttpServletRequest的setCharacterEncoding() 方法 -->
    <constant name="struts.i18n.encoding" value="UTF-8" />
    
    <!--設置瀏覽器是否緩存靜態內容,默認值為true(生產環境下使用),開發階段最好關閉 -->
    <constant name="struts.serve.static.browserCache" value="false" />

    <!--設置struts配置文件修改后,系統是否自動重新加載該文件,,默認為false(生產環境下使用) ,開發階段最好打開 -->
    <constant name="struts.configuration.xml.reload" value="true" />

    <!--開發模式下使用,這樣可以打印詳細的錯誤信息 -->
    <constant name="struts.devMode" value="true" />

    <!--默認的視圖主題, 該Struts標簽的樣式 -->
    <constant name="struts.ui.theme" value="simple" />

    <!--與spring整合時,指定由spring負責action對象的創建 -->
    <constant name="struts.objectFactory" value="spring" />

    <!--該屬性設置Struts2是否支持動態方法調用,該屬性的默認值是true,如果需要關閉動態方法的調用,屬性為false -->
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />

    <!--上傳文件的大小限制 -->
    <constant name="struts.multipart.maxSize" value="10240000" />

    <!-- 指定需要Struts2處理的請求后綴: 設置常量“struts.action.extension”進行修改, 多個后綴名,用逗號隔開 -->
    <constant name="struts.action.extension" value="do,action" />

2 package元素

<package name="default" namespace="/" extends="struts-default">

Struts2框架會把action,result等元素組織在一個名為package(包)的邏輯單元中.Struts的package很想java中的包,但與java包不同的是,Struts2中的包可以”繼承”已經定義好的包,

我們自定義的package要直接或間接的繼承 struts-default的包.

       package的屬性:

  • name 屬性:為必需並且唯一的,用來指定包的名稱,便於被其他包繼承
  • extends屬性類似Java的extends關鍵字,指定繼承那個包
  • namespace是一個可選屬性,該屬性定義該包中action的命名空間,如果沒有設置該屬性,則action被放入默認命名空間中.Struts2空間使用action的名稱和它所在包的命名空間來標識一個action,默認的命名空間用””表示,也可以使用”/”定義一個根命名空間,注意兩者是有區別的.如果請求Web應用程序路徑下的action,則框架在根命名空間中查找對應的action.

3.action元素

對於Struts2應用的開發者而言,Action才是應用的核心,開發者需要提供大量的Action類,並在struts.xml文件中配置Action.Action主要三個作用:

        1.action最重要的作用是為給定的請求封裝需要做的實際工作(調用特定的業務處理類);

        2.為數據的轉移提供場所

     3.Action必須幫助框架決定由哪個結果呈現請求響應

Action元素的屬性:

  1.method屬性

    在之前的程序中,每實現一個功能都會去創建一個Action.並且完成相應的方法,那么是否可以在同一個Action中實現不同的功能呢?答案是可以的,那我們就需要使用到

   action元素的method屬性實現在同一個Action中處理不同的請求。  

package org.suke.struts.web.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 一個Action可以包含多個請求處理方法
 * @author Administrator
 *
 */
public class UserAction extends ActionSupport {
    
    /**
     * 處理登錄請求的方法
     * @return
     */
    public String login(){
        return SUCCESS;
    }
    
    /**
     * 處理注冊請求的方法
     * @return
     */
    public String register(){
        
        return SUCCESS;
    }
}

   struts.xml的配置

  

    在上面的配置文件中,可以看到配置文件中分別定義了兩個action元素,每個action元素的name屬性是不同的,但是其指向的實現類的引用卻是相同的.那么,Struts2在接收請求后通過method屬性,

   確定該執行同一個Action中哪一個方法,也就是說,如果用戶請求的是login.action,那么久調用UserAction的login()方法,如果是register.action,則調用register()方法。

2.動態調用DMI:

  不使用method實現統一.

<action name="userAction" class="org.suke.struts.web.action.UserAction">
            <result name="success">/index.jsp</result>
</action>

  然后再在index.jsp中定義如下鏈接:

<a href="<%=path %>/userAction!login.action">登錄</a><br>
<a href="<%=path %>/userAction!register.action ">注冊</a><br>

  注意查看上面的鏈接地址,它們都是針對UserAction,然后再加地上“!+UserAction中相應的方法名”,最后再寫上.action即可以訪問到統一頁面index.jsp。這樣做雖然能減少頁面,

  但是由於它們實質用到的是同一個Action,所以這就意味着我們要使用的攔截器相同,相同的跳轉result。實際中這種方式很少使用,在此略作了解。

  如果不想使用動態方法調用,我們可以通過常量來關閉,即在struts.xml中增加如下配置:

<constant name="struts.enable.DynamicMethodInvocation" value="false"/>

 

3 .Action的通配符的使用

  在配置<action../>元素時,需要指定name,class和method屬性,其中name屬性支持通配符,然后可以在method屬性使用表達式,通配符用”* ”表示.表示匹配任意的字符串。

<action name="*User" class="org.suke.struts.web.action.UserAction" method="{1}">
            <result name="success">/{1}.jsp</result>
        </action>

 

  在action元素的name屬性中使用星號,允許這個Action匹配所有以User結束的URI,如loginUser.action.配置該action元素時,還指定了method屬性,該屬性使用一個表達式{1},

  該表達式的值就是name屬性值中第一個*的值.例如,當請求為loginUser.action時,通配符匹配的是login,那么這個值將替換{1},最終請求loginUser.action,將由UserAction的login()方法執行。

4. 配置默認的Action

  如果請求一個不存在的Action,那么結果將會在頁面上呈現HTTP404錯誤,為了解決這個問題.Struts2框架允許指定一個默認的Action,即如果沒有一個Action匹配請求,那么默認的Action被執行.

<!-- 使用默認的action -->
        <default-action-ref name="defaultAction"></default-action-ref>
        <!-- 配置默認的action -->
        <action name="defaultAction">
            <result>/error.jsp</result>
        </action>

 

5. Result的配置

  1.Result的常用結果類型

以上對type類型作簡要的說明,下面來看實例:當一個Action處理后要返回的Result是另一個Action時,作如何配置,關鍵就是配置type類型。

步驟一:建立兩個Action:TestAction、Test2Action
步驟二:web.xml配置省略。struts.xml主要配置內容如下:

<package name="resultTest" extends="struts-default">
        <action name="test" class="com.asm.TestAction">
            <result name="success" type="chain">
                <param name="actionName">test2</param>
            </result>
        </action>

        <action name="test2" class="com.asm.Test2Action">
            <result name="success">/test2Suc.jsp</result>
        </action>    
</package>

說明:在名為“test”的action中,我們配置result元素的type類型值為chain,意為將繼續把Action傳遞到下一個名為test2的Action中去,在test2.action中會把頁面轉向到test2Suc.jsp中去。

   在type類型為chain時,它的param有4個值可配,除了這里用到的name=”actionName”外(必須配置,否則報錯),還有name=namespace|method|skipActions。

   其中namespace指定要轉向到action的名字空間,由於此處是轉到Action位於同一個namespace下,而namesapace的默認值the current namespace

   所以可以省略不寫(需要說明的是如果要跳到別的名稱空間的action中去,除了使用namespace指定外,還可以用:/要跳去action所在名稱空間的值/要跳去的action的name值)。

        Method用於指定轉向到一個目標action所調用的方法,默認是調用下一個action的execute方法,所以此處仍可以省略。

        SkipActions是一個可選的屬性,一般不用。具體可以參看chain所對應類的api幫助。
        在本實例中,我們還在TestAction中設定一個username字段,並在execute方法執行為它賦了值,並在test2Suc.jsp中引用了此值。其實這種做法在web開發中還是很有用處,

   比如可以代替隱藏域。需要注意的是之所以在action的傳遞中能把設定的這個值保存下去,主要是因為轉向都是服務器跳轉。

        如果我們跳轉時采取了客戶端跳轉,也就是重定向,比如在test2 action的result中指定type類型為redirect,要想傳遞參數可以在result指向的jsp頁面中附加參數即可,我們可以在test2 action的result中寫成:

<result name="success" type="redirect">/test2Suc.jsp?username=${username}</result> 

 

   隨后在test2Suc.jsp頁面中引用時會出現三個問題:

   1.EL表達式引用失效,(EL表達式應該使用${param.username}形式)。我們也可以使用<%=request.getParameter("username")%>獲取參數值。

   2.由於在前面的TestAction中設定的值為中文,而附加到這里的uri請求的參數后面時會出現亂碼問題。(可以使用URI編碼再解碼解決此問題)

   3.值棧取值失效:因為每一次request共享同一個值棧,所以服務器端的forward跳轉也是能共享同一值棧得。但是着當test action執行后把請求交由test2 action時,

    test2 action采取的是redirect重定向到test2Suc.jsp頁面,這時其實就是重發的一次request,所以在test action保存的值棧內容全部失效。這也就是為什么我們要附加參數的原因。

    而參數是保存在actionContext中,所以采用了#的方式來取出值。圖示說明: 

  2.  全局結果

  之前我們配置的結果都在action元素的內部,這些結果不能被其他的Action使用,在一些情況下,多個Action可能需要訪問同一個結果,這時需要配置全局結果來滿足多個Action共享一個結果.

<!-- 配置全局的Result -->
        <global-results>
            <result name="success">/success.jsp</result>
            <result name="input" type="redirect">/login.jsp</result>
        </global-results>

   全局結果同樣也使用result元素配置,與action配置result元素的區別在於:全局結果需要在global-results元素中嵌套result元素,如果在Action中的result元素名稱與全局結果的名稱相同時,

  Action的result元素將會覆蓋全局result結果.也就是說:Action處理用戶請求結束后,會先在本Action中的result結果中搜索域邏輯視圖名隊員的結果,

  只有當在Action中無法匹配與邏輯視圖名對應的結果時,才會去尋找全局結果並執行,

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM