Struts攔截器及Struts.xml文件詳解(轉載)

struts2的工做流程

用戶請求
       ——>    StrutsPrepareAndExecuteFilter
       ——>    Interceptor
       ——>    Action
       ——>    Result
       ——> Jsp/html
       ——> 響應

Struts2攔截器

攔截器(interceptor)是Struts2最強大的特性之一,攔截器可讓你在Action和result被執行以前或以後進行一些處理。同時,攔截器也可讓你將通用的代碼模塊化並做爲可重用的類。Struts2中的不少特性都是由攔截器來完成的。例如params攔截器將HTTP請求中的參數解析出來,並設置爲Action的屬性。servlet-config攔截器直接將HTTP請求中的HttpServletRequest對象化HttpServletResponse對象傳給Action。html

p_w_picpath

Struts2中內置類許多的攔截器,它們提供了許多Struts2的核心功能和可選的高級特性。這些內置的攔截器在struts-default.xml中配置。只有配置了攔截器,攔截器才能夠正常的工做和運行。在struts-default.xml中攔截器的配置片斷爲:java

<package name="struts-default" abstract="true">  ①
    <interceptors>
        <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>  ②
        <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
        //…其餘攔截器配置
        <interceptor-stack name="defaultStack">  ③
              <interceptor-ref name="exception"/>
              <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="i18n"/>
                //…其餘攔截器的引用
          </interceptor-stack>   
    </interceptors>
    <default-interceptor-ref name="defaultStack"/>  ④
</package>
① package將屬性abstract設置爲true,表明此package爲一個抽象的package。抽象package和非抽象package的區別在於抽象的package中不能配置action。
② name屬性指定攔截器的名字,class屬性指定攔截器的徹底限定名。
③ 多個攔截器能夠組成攔截器棧。name屬性爲攔截器棧的名字。
④ 指定當前package的默認攔截器(棧)。當前指定的默認攔截器棧爲defaultStack,該攔截器棧是Struts2運行的一個基本攔截器棧,通常咱們不用在本身配置它,由於在大多數狀況下,咱們自定義的package是繼承自struts-default這個package的。


咱們以Struts2內置的timer攔截器爲例,來學習如何在咱們的應用中添加其餘的攔截器。timer攔截器能夠統計action執行的時間。咱們能夠修改package中默認的攔截器,那麼將替換掉struts-default中配置的defaultStack攔截器棧,致使Struts2沒法正常運行,好比沒法獲取表單的值等等。那麼該如何正確的配置呢?能夠在添加新的攔截器的基礎上加入defaultStack攔截器棧,這樣就能夠保證defaultStack攔截器棧的存在。spring

<package name="myStruts" extends="struts-default">
    <interceptors>
        <interceptor-stack name="myInterceptor">  ①
            <interceptor-ref name="timer"/> 
            <interceptor-ref name="defaultStack"/> 
        </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="myInterceptor"/>  ②
    <action name="userAction"
        class="com.kay.action.UserAction">
        <result name="success">suc.jsp</result>
        <result name="input">index.jsp</result>
        <result name="error">err.jsp</result>
    </action>
</package>
① 添加一個自定義的攔截器棧,並在其中包含time攔截器和defaultStack攔截器棧。
② 設置當前的package的默認攔截器棧爲自定義的攔截器棧。

修改package的默認攔截器會應用的package中的全部Action中,若是隻想給其中一個Action添加攔截器,則能夠這樣來作:apache

<package name="myStruts" extends="struts-default">
    <interceptors>
        <interceptor-stack name="myInterceptor">
            <interceptor-ref name="timer"/>
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
    </interceptors>
    <action name="userAction"
        class="com.kay.action.UserAction">
        <interceptor-ref name="myInterceptor"/>  ①
        <result name="success">suc.jsp</result>
        <result name="input">index.jsp</result>
        <result name="error">err.jsp</result>
    </action>
</package>
                                                               
① 給UserAction添加攔截器。

若是要建立本身的攔截器,只須要實現Interceptor接口,該接口中定義瞭如下三個方法:jsp

void init():ide

在攔截器初始化以後,在執行攔截以前,系統調用該方法。對於一個攔截器而言,init方法只會被調用一次。模塊化

String intercept(ActionInvocation invocation) throws Exception:組件化

該方法是攔截器的攔截方法,返回一個字符串,系統將會跳轉到該字符串對應的視圖資源。該方法的ActionInvocation參數包含了被攔截的Action的引用,能夠經過該對象的invoke方法,將控制權轉給下一個攔截器或者轉給Action的execute方法。post

void destroy():單元測試

該方法與init方法對應,在攔截器示例被銷燬以前,系統將會調用該方法。

除了Interceptor接口外,Struts2中還提供了一個AbStractInterceptor類,該類提供了一個init和destroy方法的空實現。若是不須要就不用重寫這兩個方法,可見繼承自AbstractInterceptor類可讓咱們構建攔截器時變得簡單。

下面咱們構建本身的攔截器,實現timer攔截器的效果。

public class MyInterceptor extends AbstractInterceptor {
    public String intercept(ActionInvocation invocation) throws Exception {
        long startTime = System.currentTimeMillis();  ①
        String result = invocation.invoke();  ②
        long endTime = System.currentTimeMillis();  ③
        System.out.println("Action執行共須要" + (endTime - startTime) + "毫秒");
        return result;
    }
}
① 得到Action執行的開始時間。
② 將控制權交給下一個攔截器,若是該攔截器是最後一個攔截器,則調用Action的execute方法。
③ 得到Action執行的結束時間。

在配置文件struts.xml中配置攔截器:

<package name="myStruts" extends="struts-default">
    <interceptors>
        <interceptor name="myTimer" class="com.kay.interceptor.MyInterceptor"></interceptor>  ①
        <interceptor-stack name="myInterceptor">
            <interceptor-ref name="myTimer"/>  ②
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
    </interceptors>
    <action name="userAction"
        class="com.kay.action.UserAction">
        <interceptor-ref name="myInterceptor"/>
        <result name="success">suc.jsp</result>
        <result name="input">index.jsp</result>
        <result name="error">err.jsp</result>
    </action>
</package>
                                                    
① 定義一個新的攔截器,name屬性爲攔截器的名字,class屬性爲攔截器的徹底限定名。
② 在攔截器棧中加入新的攔截器。

從攔截器的運行原理上和咱們之前學習的Servlet中的過濾器是否是很相像呢?其實它們只有一個重要的區別,就是攔截器的工做是不依賴容器的,這會在進行單元測試時變得簡單。



struts2.0中struts.xml配置文件詳解

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" >
<struts>
    <!-- include節點是struts2中組件化的方式 能夠將每一個功能模塊獨立到一個xml配置文件中 而後用include節點引用 -->
    <include file="struts-default.xml"></include>
                                             
                                             
    <!-- package提供了將多個Action組織爲一個模塊的方式
        package的名字必須是惟一的 package能夠擴展 當一個package擴展自
        另外一個package時該package會在自己配置的基礎上加入擴展的package
        的配置 父package必須在子package前配置
        name:package名稱
        extends:繼承的父package名稱
        abstract:設置package的屬性爲抽象的 抽象的package不能定義action 值true:false
        namespace:定義package命名空間 該命名空間影響到url的地址,例如此命名空間爲/test那麼訪問是的地址爲http://localhost:8080/struts2/test/XX.action
     -->
    <package name="com.kay.struts2" extends="struts-default" namespace="/test">
        <interceptors>
            <!-- 定義攔截器
                name:攔截器名稱
                class:攔截器類路徑
             -->
            <interceptor name="timer" class="com.kay.timer"></interceptor>
            <interceptor name="logger" class="com.kay.logger"></interceptor>
            <!-- 定義攔截器棧 -->
            <interceptor-stack name="mystack">
                <interceptor-ref name="timer"></interceptor-ref>
                <interceptor-ref name="logger"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
                                                 
        <!-- 定義默認的攔截器 每一個Action都會自動引用
         若是Action中引用了其它的攔截器 默認的攔截器將無效 -->
        <default-interceptor-ref name="mystack"></default-interceptor-ref>
                                                 
                                                 
        <!-- 全局results配置 -->
        <global-results>
            <result name="input">/error.jsp</result>
        </global-results>
                                                 
        <!-- Action配置 一個Action能夠被屢次映射(只要action配置中的name不一樣)
             name:action名稱
             class: 對應的類的路徑
             method: 調用Action中的方法名
        -->
        <action name="hello" class="com.kay.struts2.Action.LoginAction">
            <!-- 引用攔截器
                name:攔截器名稱或攔截器棧名稱
             -->
            <interceptor-ref name="timer"></interceptor-ref>
                                                 
            <!-- 節點配置
                name : result名稱 和Action中返回的值相同
                type : result類型 不寫則選用superpackage的type struts-default.xml中的默認爲dispatcher
             -->
         <result name="success" type="dispatcher">/talk.jsp</result>
         <!-- 參數設置
             name:對應Action中的get/set方法
         -->
         <param name="url">http://www.sina.com</param>
        </action>
    </package>
</struts>
相關文章
相關標籤/搜索