Struts之攔截器

     今天看了看攔截器,不由得想對攔截器做個描述,在我們進行項目攔截器編寫的時候,讓我們先把前期的配置給搭建好。
首先我們需要在web.xml中配置信息如下
   <filter>
  <filter-name>struts2</filter-name>
          <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  <init-param>
           <param-name>actionPackages</param-name>
           <param-value>com.summer.action.server</param-value>
  </init-param>
   </filter>
      //    org.apache.struts2.dispatcher.FilterDispatcher這個已經過時了、
      //  org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecute替代以上

    // <filter>
      //         <filter-name>struts2</filter-name>
     //         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
   // </filter>

<struts>
  <package name="methodFilter" extends="struts-default">
      <interceptors>
           <interceptor name="myInterceptor11" class="com.sharme.interceptor.MyInterceptor11">
                   <param name="hello">world</param>
           </interceptor>
           <!--<param name="hello">world</param>表示爲攔截器增加一個名爲hello值爲world的屬性-->
           <!--但是這裏也只是爲hello賦了初值爲world,如若在下面的<action>中配置使用該攔截器的時候-->
           <!--增加了<param name="hello">welcome</param>,那麼則最後攔截器累中的hello屬性值即爲welcome-->
         
           <interceptor name="myInterceptor21" class="com.sharme.interceptor.MyInterceptor21"/>
      </interceptors>

      <action name="methodFilter" class="com.sharme.action.MethodFilterAction" method="test">
           <result name="success">/methodFilteResult.jsp</result>
           <interceptor-ref name="defaultStack"/>
           <interceptor-ref name="myInterceptor11"/>
      </action>

</struts>

以上是對於 "方法過濾攔截器" 的使用:
   
  默認的情況下,攔截器會攔截Action中的所有的方法,這裏不包括setter或getter方法,這時就可以使用方法過濾攔截器指定的方法,這是一種更加
細化的攔截器的配置方式,它可以細化到攔截具體的某個方法,而不是攔截某個Action,因爲攔截Action是一種粗粒度的實現方式,使用includeMethods
指明攔截器所要攔截的方法。使用excludeMethods指明攔截去不再攔截的方法,這裏excludeMethods和includeMethods是在MethodFilterInterceptor
類中定義的成員變量,而且只要includeMethods進來的方法就一定會被攔截,而不管是否已經把它excludeMethods在外了
也就是說includeMethods的優先級要高於excludeMethods
也可以使用<param name="includeMethods"/>在上面定義攔截器的時候指定全局性的過濾的方法
    區別:對方法的過濾有全局性和局部性的區分。而當發生衝突時,就依照就近原則,以局部性的配置爲準,所謂的發生衝突,指的是類似於
全局中有一個includeMethods配置,而局部中也有一個includeMethods配置,另外,還有一種情況,假設全局性過濾定義爲<param name="includeMethods">
test</param>而在局部性過濾中定義爲<param name="excludeMethods">test</param>將生效,即攔截Action中的test()方法,這個時候全局中配置的攔截
局部中配置的是不攔截,二者並沒有發生衝突,所有仍是以includeMethods優先級高,可以認爲在局部的配置中,已經隱含的把<param name="includeMethods">
test</param>繼承過來了

 

實現Interceptor接口的自定義攔截器MyInterceptor.java

 public class MyInterceptor implements Interceptor{
   //這裏屬性名要與struts.xml配置的<param name=""/>中的name值相同
   //然後struts2會自動將struts.xml中配置的world值賦值到這裏的hello屬性中
   //前提是要提供setter和getter方法,只要符合JavaBean的要求即可

    private String hello;
    public String getHello(){return hello;}

    public void setHello(String hello){this.hello=hello;}

    //initialization method
    public void init(){
        System.out.println("----MyInterceptor initialization method invoked---");
   }
  
   //destory method
    public void destory(){
        System.out.println("----MyInterceptor destory method invoked-----");
    }

   public String interceptor(ActionInvocation invocation)throws Exception{
       System.out.println("----MyInterceptor invoked begin");
       //調用invoke()方法
       //還有下一個攔截器的話,執行下一個攔截器
       //如何沒有下一個攔截器的話,就執行Action中的方法
       String result=invocation.invoke();
       System.out.println("--MyInterceptor invoked finish--------");
       return result;
   }

       
}


------下面來談談Struts2的攔截器------------
struts2中的攔截器,實際上就是用來攔截Action的。它就相當於入口和出口一樣,把Action的相關方法包裹在中間了
,過濾器可以組成過濾器鏈,也就是有多個過濾器來過濾相同的東西。攔截器同樣也有攔截器鏈,在struts2中稱爲
攔截器棧,攔截器執行的順序是按照配置的順序執行的。
   假設先配置myInterceptor1,再配置myInterceptor2,所有在執行時,先執行myInterceptor1,後執行myInterceptor2
,但是結束時,先執行myInterceptor2,後執行myInterceptor1,就好stack,壓棧和彈棧的過程
過程是:先會進入第一個攔截器,出來後再進入第二個攔截器,以此類推,最後進入Action的execute()方法,之後是進行
相反地順序。
因此invoke就是用來判斷,若還有下一個攔截器,就調用下一個攔截器,否則,直接跳到Action的execute方法


------------繼承了AbstractInterceptor類的自定義攔截器MyInterceptor3
   public class MyInterceptor3 extends AbstractInterceptor{
      public String interceptor(ActionInvocation invocation)throws Exception{
            System.out.println("---------MyInterceptor3 invoked begin");
            String result=invocation.invoke();
            System.out.println("---------MyInterceptor3 invoked finish-----");
            return result;
      }
   }

繼承AbstractInterceptor類的攔截器就不需要自己去實現init和destory方法了,在我們應用之中,更多的時候還是
繼承AbstractInterceptor而不是實現Interceptor
 

 

-------------繼承MethodFilterInterceptor攔截器

public class MyInterceptor4 extends MethodFilterInterceptor{
   
    protected String doIntercept(ActionInvocation invocation)throws Exception{
             System.out.println("------MyInterceptor4 invoked begin");

              String result=invocation.invoke();
              System.out.pritnln("----MyInterceptor4 invoked finish-----");
    }
}

MethodFilterInterceptor攔截器繼承了AbstractInterceptor,他就是一個攔截某一個具體的方法的過濾攔截器。
而MethodFilterInterceptor類已經自動實現好了Intercept方法,實際上MethodFilterInterceptor類中的Intercept
方法真正執行的是它本身的一個doIntercept()抽象方法,因此我們需要攔截某一個方法時候:只要繼承
methodFilterInterceptor類,然後實現doIntercept

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章