九、Struts2之攔截器

來源:互聯網
上載者:User
文章目錄
  • 1.配置自訂攔截器和攔截器棧
  • 3.方法過濾
一、攔截器介紹

攔截器是Struts2最重要的組成部分,因為Struts2的大部分操作都是通過他完成的,以下列舉了一些內建攔截器:

(1)params :攔截HTTP請求參數,並完成類型轉換

(2)fileUpload:檔案上傳攔截器;

(3)conversionError:處理類型轉換錯誤的攔截器;

(4)exception:處理異常的攔截器,因此在execute方法中,才可以安心拋出異常;

(5)i18n:處理國際化攔截器;

(6)static-params:用於在struts.xml中注入action屬性值;

(7)validation:在xml檔案中配置的輸入校正攔截器;

(8)workflow:處理手動校正的攔截器;

以上內建攔截器都在struts2-core-Xxx.jar\struts-default.xml中定義,因此在定義<package>時需要填寫 extends="struts-default",這樣能夠自動繼承這些攔截器;

而我們還可以自己定義攔截器,不過注意,如果配置了自訂攔截器,則會讓內建攔截器消失,因此我們必須要顯式地引用內建攔截器,如下 <interceptor name="defaultStack"/>;

Struts2通過可插拔設計,可以添加、刪除任意攔截器,非常靈活;

攔截器&攔截器棧

攔截器棧是由多個攔截器構成的,在使用時可以把他當作一個“大一點的攔截器”,除了定義不同,使用起來是相同的;

攔截器棧應用:多個攔截器同時使用時,方便管理;

攔截器棧

    攔截器1

    攔截器2

    攔截器3

 

攔截器的使用:攔截器配置在<action>中,即為某個Action配置一個或多個攔截器, 即執行Action方法之前會被攔截器攔截,並執行攔截器方法;

二、自訂攔截器

 

1.配置自訂攔截器和攔截器棧

 

定義攔截器或攔截器棧的根項目為<interceptors>,而此元素是<package>的子項目;


(1)定義攔截器:<interceptors>的子項目

<interceptor name="攔截器名" class="實作類別"/>

註:如果需要傳入參數,則表示攔截器類屬性的預設值;

<interceptor name="攔截器名" class="實作類別">    <param name="name">value</param></interceptor>

(2)引用攔截器:<action>或<interceptor-stack>的子項目

如果是<action>的子項目,則表示在action中配置一個攔截器;

<interceptor-ref name="攔截器名"/>

註:如果需要傳入參數,則表示使用攔截器時類屬性的值,將覆蓋定義攔截器時傳入的參數;

<interceptor-ref name="攔截器名">    <param name="name">value</param></interceptor-ref>

(3)定義攔截器棧:<interceptors>的子項目

<interceptor-stack name="攔截器棧名">

    <interceptor-ref name="攔截器名"/>

    <interceptor-ref name="攔截器名"/>

</interceptor-stack>

(4)引用攔截器棧:<action>的子項目

<interceptor-ref name="攔截器棧名"/>

註:這裡傳遞參數方法比較特殊,因為攔截器棧中有多個攔截器,因此必須以如下形式執行參數:

<interceptor-ref name="攔截器棧名">

<param name="interceptorName.attrName">value</param>

</interceptor-ref>

(5)定義預設攔截器:<package>的子項目

<default-interceptor-ref name="攔截器或攔截器棧名"/>

註:可以在此處傳入參數:

<default-interceptor-ref name="預設攔截器名">

    <param name="name">value</param>

</default-interceptor-ref>

預設攔截器使用時機:當action中沒有顯式地引用攔截器,則會使用預設攔截器;

 

2.定義攔截器類

實現Interceptor介面,並實現方法:

(1)public void init();        //初始化,一般為空白

(2)public void destroy();        //銷毀,一般為空白

(3)public String interceptor(ActionInvocation invocation)throws Exception;    //實現攔截功能,傳回值為execute方法傳回值;

String result = invocation.invoke()即可調用攔截器攔截的Action的execute()方法,並返回邏輯視圖;
public String interceptor(ActionInvocation invocation)throws Exception{

        //調用execute()方法之前

        String result = invocation.invoke();

        //調用execute()方法之後

        return result;

注意:

(1)在使用自訂攔截器時,會丟失預設內建攔截器,因此需要顯式引用預設攔截器棧:<interceptor-ref name="defaultStack"/>

(2)如果在一個Action中配置了兩個攔截器,則如果攔截器A在攔截器B之前引用,即:

<action>

<interceptor-ref name="A"/>

<interceptor-ref name="B"/>

</action>

則雖然在兩個攔截器中都調用了invocation.invoke(),但是只會執行一遍Action方法;Action方法執行之前,攔截器A比攔截器B先執行;Action方法執行之後,則攔截器B比攔截器A先執行;

即結果為:

 A攔截器語句

B攔截器語句

execute

B攔截器語句

A攔截器語句

代碼執行個體:

HelloAction.java

package org.xiazdong.action;import com.opensymphony.xwork2.ActionSupport;public class HelloAction extends ActionSupport {public String execute()throws Exception{System.out.println("execute...");return SUCCESS;}}

Interceptor01.java

package org.xiazdong.interceptor;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.Interceptor;public class Interceptor01 implements Interceptor {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void destroy() {}@Overridepublic void init() {}@Overridepublic String intercept(ActionInvocation invocation) throws Exception {System.out.println("name屬性:"+name);System.out.println("execute方法之前...");String result = invocation.invoke();System.out.println("execute方法之後...");return result;}}

struts.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts><constant name="struts.devMode" value="true" /><package name="default" namespace="/" extends="struts-default"><interceptors><interceptor name="interceptor01" class="org.xiazdong.interceptor.Interceptor01"><param name="name">xiazdong</param></interceptor><interceptor-stack name="stack"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="interceptor01"></interceptor-ref></interceptor-stack></interceptors><action name="hello" class="org.xiazdong.action.HelloAction"><interceptor-ref name="stack"></interceptor-ref><result>/index.jsp</result></action></package></struts>

3.方法過濾

預設自訂攔截器將會攔截Action的所有方法,比如在Action中定義了login()方法、regist()方法,則預設會攔截兩個方法,如果只想攔截login()方法,則需要通過如下步驟實現過濾:

(1)繼承 MethodFilterInterceptor類;

(2)重寫public String doIntercept(ActionInvocation invocation)throws Exception;此方法和intercept方法功能一致,只是名字不一樣;

(3)在struts.xml中配置參數進行過濾:在<interceptor-ref>的子項目中設定:

<param name="excludeMethods">不過濾的方法1,不過濾的方法2</param>、<param name="includeMethods">需要過濾的方法</param>

注意:如果一個方法在includeMethods和excludeMethods參數中同時列出,則還是會被攔截;


代碼執行個體:如果Action中提供了login()、regist()方法,則struts.xml中如下配置,可以實現login()不被攔截器攔截:struts.xml
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts><constant name="struts.devMode" value="true" /><package name="default" namespace="/" extends="struts-default"><interceptors><interceptor name="interceptor01"class="org.xiazdong.interceptor.Interceptor01"><param name="name">xiazdong</param></interceptor><interceptor-stack name="stack"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="interceptor01"><param name="excludeMethods">login</param></interceptor-ref></interceptor-stack></interceptors><action name="hello" class="org.xiazdong.action.HelloAction"><interceptor-ref name="stack"></interceptor-ref><result>/index.jsp</result></action></package></struts>
補充:PreResultListener應用在Action的介紹中也介紹過這個類,是用於在Action方法執行之後、轉入物理視圖之前被調用;
這個類也可以在攔截器類中被添加,則只要應用該攔截器的action都會起作用,步驟如下:
(1)定義MyPreResultListener:
public class MyPreResultListener implements PreResultListener{
public void beforeResult(ActionInvocation invocation,String resultCode);
}(2)在intercept方法中添加invocation.addPreResultListener(new MyPreResultListener());
即可;
代碼:
MyPreResultListener.java
package org.xiazdong.interceptor;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.PreResultListener;public class MyPreResultListener implements PreResultListener {@Overridepublic void beforeResult(ActionInvocation arg0, String arg1) {System.out.println("beforeResult...");}}

Interceptor01.java

package org.xiazdong.interceptor;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.Interceptor;import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;public class Interceptor01 extends MethodFilterInterceptor{@Overridepublic String doIntercept(ActionInvocation invocation) throws Exception {invocation.addPreResultListener(new MyPreResultListener());System.out.println("execute1方法之前...");String result = invocation.invoke();System.out.println("execute1方法之後...");return result;}}

結果如下:

 execute1方法之前...
regist...
beforeResult...
execute1方法之後...

可以看出,此方法在Action方法一執行完就觸發PreResultListener,比攔截器先執行;


最後配上一張圖作為結尾:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.