java之struts2之攔截器


1.struts2能完成數據的設置,數據的封裝,數據的類型轉換,數據的校驗等等。struts2是如何來完成這些功能的?struts2的所有功能都是由攔截器來完成的

2.攔截器是struts2的核心。攔截器是一個類似於過濾器的類。在執行action的處理方法前會 先執行攔截器,然后再執行action的處理方法,然后再執行攔截器,再響應

3. struts2的所有功能都是由攔截器來實現的,而攔截器在struts2中時可以自由配置和自由裝配的。所以struts2的所有功能也都是可插拔的。並且struts2中的攔截器是可以自定義的,所以如果struts2沒有提供項目所需的功能時,可以通過自定義攔截器來實現

4. struts2的攔截器有哪些,分別有什么功能:

  • alias : 對於HTTP請求包含的參數設置別名
  • autowiring : 將某些JavaBean實例自動綁定到其他Bean對應的屬性中。有點類似Spring的自動綁定,在Spring部分會詳細說明
  • chain : 在Web項目開發中,以前使用Struts開發的時候經常碰到兩個Action互相傳遞參數或屬性的情況。該攔截器就是讓前一個Action的參數可以在現有Action中使用。
  • conversionError : 從ActionContext中將轉化類型時候發生的錯誤添加到Action的值域錯誤中,在檢驗的時候經常被使用來顯示類型轉化的錯誤信息
  • cookie : 從Struts2.0.7版本開始,可以把cookie注入Action中可設置的名字或值中
  • createSession : 自動創建一個HTTP的 Session, 尤其是對需要HTTP的Session的攔截器特別有用。比如下面介紹的TokenInterceptor
  • debugging : 用來對在視圖間傳遞的數據進行調試
  • execAndWait : 不顯示執行Action, 在視圖上顯示給用戶的是一個正在等待的頁面,但是Action其實是在背后正在執行着。該攔截器尤其在對進度條進行開發的時候特別有用。
  • exception : 將異常和Action返回的result相映射
  • fileUpload : 支持文件上傳功能的攔截器
  • i18n : 支持國際化的攔截器
  • logger : 擁有日志功能的攔截器
  • modelDriven : Action執行該攔截器的時候,它可以從一個scope范圍檢索和存儲model值,通過調用setModel方法去設置model的值
  • params : 將HTTP請求中包含的參數值設置到Action中
  • prepare : 假如Action繼承了Preparable接口,則會調用prepare方法
  • staticParams : 對於在struts.xml文件中的Action中設置的參數設置到對應的Action中
  • scope : 在session或者application范圍中設置Action的狀態
  • servletConfig : 該攔截器提供訪問包括HttpServletRequest和HttpServletResponse對象的Map方法
  • timer : 輸出Action的執行時間
  • token : 避免重復提交的校驗攔截器
  • tokenSession : 和token攔截器類似,但它還能存儲提交的數據到session里
  • validation : 運行在action-validation.xml文件中定義的校驗規則。(數據校驗部分)
  • workflow : 在Action中調用validate檢驗方法。如果Action有錯誤則返回到 input 視圖
  • store : 執行校驗功能的時候,該攔截器提供存儲和檢索Action的所有錯誤和正確信息的功能
  • checkbox : 視圖中如果有checkbox存在的情況,該攔截器自動將unchecked的checkbox當做一個參數(通常為false)記錄下來。這樣可以用一個隱藏的表單值來記錄所有未提交的checkbox,而且缺省unchecked的checkbox值是布爾類型的,如果視圖中checkbox的值設置的不是布爾類型,它就會被覆蓋成布爾類型的值
  • profiling : 通過參數來激活或者不激活分析檢測功能,前提示Web項目是在開發模式下。(涉及到調試和性能檢驗時使用)
  • roles : 進行權限配置的攔截器,如果登錄用戶擁有相應的權限才去執行某一特定的Action

5.struts2中攔截器定義的位置在struts-default.xml中

6.自定義攔截器步驟

a) 編寫類,實現Interceptor接口

 

public class ActionExecuteTimeInterceptor implements Interceptor{

    @Override
    public void destroy() {
        
    }

    @Override
    public void init() {
        
    }

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        long start=System.currentTimeMillis();
        //執行下一個攔截器  如果下面沒有攔截器則執行action的處理方法,並將結果返回
        String result = invocation.invoke();
        System.out.println("執行時間為:"+(System.currentTimeMillis()-start));
        return result;
    }

}

 

b) struts.xml中配置攔截器

 

<!-- 攔截器配置 -->
<interceptors>
   <!-- 配置自定義攔截器
        name 是唯一的
        class 是自定義攔截器的完全限定名
   -->
   <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor>
</interceptors>

c) 在對應action中 引用自定義攔截器

<package name="default" extends="struts-default" namespace="/">
        <!-- 攔截器配置 -->
        <interceptors>
            <!-- 配置自定義攔截器 name 是唯一的 class 是自定義攔截器的完全限定名 -->
            <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor>
        </interceptors>
        <action name="add" class="cn.sxt.action.UserAction" method="add">
            <result>/success.jsp</result>
            <!-- 在action中引用自定義的攔截器 -->
            <interceptor-ref name="executeTime"></interceptor-ref>
        </action>
    </package>

7.自定義攔截器有兩種方式實現一種實現Interceptor接口還可以繼承AbstractInterceptor類來實現:如:

public class HelloInterceptor extends AbstractInterceptor{

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("hello interceptor 被執行");
        return invocation.invoke();
    }
    
}

8.如果引用了自定義攔截器,那么struts2的攔截器將不再起作用。如果需要使用struts2的攔截器需要手動引入。

<action name="add" class="cn.sxt.action.UserAction" method="add">
            <result>/success.jsp</result>
            <!-- 在action中引用自定義的攔截器 -->
            <interceptor-ref name="executeTime"></interceptor-ref>
            <interceptor-ref name="helloInterceptor"></interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
        </action>

9.當自定義攔截器比較多時,在action中引用攔截器將會變得比較麻煩,所以呢,struts2提供了攔截器棧攔截器棧是用來引用已經定義好的攔截器的。一個攔截器棧可以包括多個攔截器,引用攔截器棧的方式和引用攔截器的方式一樣。

<!-- 攔截器配置 -->
        <interceptors>
            <!-- 配置自定義攔截器
                name 是唯一的
                class 是自定義攔截器的完全限定名
             -->
            <interceptor name="helloInterceptor" class="cn.sxt.interceptor.HelloInterceptor"></interceptor>
            <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor>
            <!-- 定義攔截器棧 -->
            <interceptor-stack name="myStack">
                <interceptor-ref name="executeTime"></interceptor-ref>
                <interceptor-ref name="helloInterceptor"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <action name="add" class="cn.sxt.action.UserAction" method="add">
            <result>/success.jsp</result>
            <!-- 在action中引用自定義的攔截器 -->
            <interceptor-ref name="myStack"></interceptor-ref>
        </action>

10.struts2如果沒有自定義攔截器時,action類會引用默認的攔截器棧如果有自定義攔截器后,想自定義攔截器設置為默認攔截器應該如何操作?

package中去定義一個default-interceptor-ref即可

<!-- 設置默認攔截器 -->
        <default-interceptor-ref name="myStack"></default-interceptor-ref>
        <action name="add" class="cn.sxt.action.UserAction" method="add">
            <result>/success.jsp</result>
        </action>

11.攔截器的使用

登錄攔截器用來實現用戶登錄檢查

public class LoginInterceptor extends AbstractInterceptor{
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        //判斷執行的Action是否login.action
        //如果不是 判斷用戶是否登錄
        //如果登錄了 執行下一個攔截器,如果沒有登錄 去登錄
        //獲取執行action的名稱
        String actionName=invocation.getProxy().getActionName();
        if("login".equals(actionName)){
            return invocation.invoke();
        }
        Object obj=ServletActionContext.getRequest().getSession().getAttribute("currentUser");
        if(obj!=null){
            return invocation.invoke();
        }
        return Action.LOGIN;
    }
}

配置

<struts>
    <package name="default" extends="struts-default" namespace="/">
        <!-- 攔截器配置 -->
        <interceptors>
            <interceptor name="loginInterceptor" class="cn.sxt.interceptor.LoginInterceptor"></interceptor>
            <interceptor-stack name="myStack">
                <interceptor-ref name="loginInterceptor"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <default-interceptor-ref name="myStack"></default-interceptor-ref>
        <!-- 定義全局結果集 -->
        <global-results>
            <result name="login">/login.jsp</result>
        </global-results>
        <action name="login" class="cn.sxt.action.UserAction" method="login">
            <result>/success.jsp</result>
        </action>
        <action name="show" class="cn.sxt.action.UserAction" method="show">
            <result>/show.jsp</result>
        </action>
    </package>
</struts>

12.總結:

攔截器是單列的,所有action執行的都是同一個攔截器。所以在自定義攔截器時要注意線程安全的問題。攔截器只攔截action

13.注意過濾器和攔截器區別

14. 方法攔截器

方法攔截器是比攔截器更加細粒度的攔截器,只攔截方法。通過配置方法攔截器可以有效提高系統性能。

/**
 * 自定義方法攔截器
 *
 */
public class AddMethodInterceptor extends MethodFilterInterceptor{

    @Override
    protected String doIntercept(ActionInvocation invocation) throws Exception {
        System.out.println("進入方法攔截器");
        return invocation.invoke();
    }

}

配置

<!-- 配置方法攔截器 -->
            <interceptor name="addInterceptor" class="cn.sxt.interceptor.AddMethodInterceptor">
                <!-- 配置哪些方法 需要被攔截 -->
                <param name="includeMethods">add</param>
                <!-- 排除哪些方法不被攔截 <param name="excludeMethods"></param> -->
            </interceptor>

 


免責聲明!

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



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