Struts2學習筆記(5)--攔截器

Interceptor (底層經過動態代理實現)
1.建包 ...interceptor
自定義攔截器
第一種方式:
實現xwork包下的 Interceptor接口
init() {} 初始化時調用
destroy() {} 銷燬時調用
class MyInterceptor implements Interceptor {
 private String hello;
 //setter...getter...
 public void init() {
  System.out.println("init()...");
  System.out.println( hello );
 }
 public void destroy() {
  System.out.println("destroy()...");
 }
 public String intercept(ActionInvocation invocation) throws Exception {
  System.out.println("intercept()1...");
  //攔截器有攔截器站
  //invoke()將判斷是否還有下一個攔截器,有就執行下一個攔截器,沒有則開始執行被攔截的類
  String result = invocation.invoke();
  System.out.println("finish1...");
  return result;
 }
---------------------------------
第二種方式:
1.繼承 AbstractInterceptor 
  該類實現了Interceptor接口,而且空實現了init()和destroy()方法
public class MyInterceptor extends AbstractInterceptor {
 public String intercept(ActionInvocation invocation) throws Exception {
  System.out.println("intercept()2...");
  String result = invocation.invoke();
  System.out.println("finish2...");
  return result;
 }
}

----------------------------

2. struts.xml 配置
<struts>
 struts採用包名把不一樣的action區分開,相同相似功能的放在一個包裏
 包之間是能夠有繼承關係的,
 extends="struts-default" 至關於把struts2-core-2.0.11.jar下的struts-default.xml的東西給繼承過來了
 其中包括N多的攔截器
 
  <package name="包名" extends="struts-default">
  
  定義攔截器
   <interceptors>
   定義多個攔截器時能夠包含多個<interceptor>
    <interceptor name="myInterceptor" class="com....interceptor.MyInterceptor"/>
    <interceptor name="myInterceptor2" class="...">
    爲攔截器配置參數
    name對應到攔截器類中的字段屬性,該屬性須要有set、get方法
    當啓動攔截器時這項配置將會吧world做爲值賦給私有成員hello
    也能夠在引用攔截器時改變這個值
     <param name="hello">world</param>
    </interceptor>
  </interceptors>
  聲明攔截器棧
   <interceptors-stack name="myInterceptorStack">
   引用攔截器
    <interceptor-ref name="myInterceptor" />
   <interceptor-ref name="myInterceptor2" />
   攔截器棧中能夠包含攔截器棧
    <interceptor-ref name="defaultStack" />   defaultStack---Struts2默認的攔截器
   
   </interceptors-stack>
  <interceptors-stack name="myInterceptorStack2">   
   <interceptor-ref name="myInterceptor" />
   引用攔截器棧
    <interceptor-ref name="myInterceptorStack" />     
  </interceptors-stack>
  <action ...>
   <result name="...">...</result>
   ...
   使用攔截器 action被請求一次,攔截器的intercept()就被執行一次
   引用攔截器
    <interceptor-ref name="myInterceptor" />
   <interceptor-ref name="myInterceptor2" >
    使用攔截器時對hello賦值,會改變引用時的賦值
     <param name="hello">welcome</param>
   </interceptor-ref>
   <interceptor-ref name="defaultStack" />  手動導入Struts2默認的攔截器棧
   </action>
  定義默認的攔截器棧
  他會自動的把默認的攔截器附加到每個Action中去
  在一個包中,能夠有0或1個默認的攔截器棧
  若是在一個<action>中手動的指定一個攔截器,默認的攔截器就不會再自動的加到這個action裏
  只能經過手工的方式再導入一下
   <default-interceptor-ref name="defaultStack" />
 </package>
</struts>  
 
=======================================
若是調用多個攔截器,執行順序是怎樣的?
如:
<interceptors>
 <interceptor name="myInterceptor" class="..."></interceptor>
 <interceptor name="myInterceptor2" class="..."></interceptor>
</interceptors>
<interceptors-stack name="myInterceptorStack"> 
 執行順序 按 配置的順序 
 <interceptor-ref name="myInterceptor" />
 <interceptor-ref name="myInterceptor2" />
</interceptors-stack>

注:攔截器會在調用invoke()方法調用以前和以後都會執行
   攔截器1                          1 中invoke方法前的語句
     |_________攔截器2              2 中invoke方法後的語句
                     |__________
                                    |
                                 invoke()   執行invoke()方法
                      __________|
                     |
      ________攔截器2               2 中invoke方法後的語句
     |
   攔截器1                          1 中invoke方法後的語句
 
==================================================
第三中方式:指定攔截的方法
若是攔截器沒有作任何配合話,它會攔截全部的邏輯執行方法
若是<action>中method="execute" 指定了方法,它便只攔截execute方法
還能夠經過方法過濾攔截器來指定攔截或不攔截的方法

--------------------------------------------------
繼承MethodFilterInterceptor
public class MyInterceptor3 extends MethodFilterInterceptor {
 @Override
 public void init() {
  System.out.println("init3");
 }
 //intercept()已經實現好了,不用去管他
 //須要重寫一下doIntercept
 @Override
 public String doIntercept(ActionInvocation invocation) throws Exception {
  System.out.println("intercept()3...");
  String result = invocation.invoke();
  System.out.println("finish3...");
  return result;
 }
}
---------------------------------------------------
MethodFilterInterceptor中包含兩個protected的屬性
 Set includeMethods : 包含誰
 Set excludeMethods : 排除誰

<interceptors>
 <interceptor name="myInterceptor3" class="..."></interceptor>
</interceptors>

<action ...>
 <result ...>...</result>
 ...
 
 <interceptor-ref name="myInterceptor3" >
  包含                         要攔截方法 多個用逗號分開
   <param name="includeMethods">execute,test</param>
  
  排除                         不攔截的方法 多個用逗號分開
   <param name="excludeMethods">execute</param>
 </interceptor-ref>
 <interceptor-ref name="defaulteStack" />
</action>

注:
若是 既包含includeMethod和excludeMethod,includeMethod必定會被攔截無論是否以把它排除
 

================
     補充
================
-------------------------------
      Java的過濾器 Filer:
-------------------------------
3個方法:
init( FilterConfig filterConfig ) {} 初始化時調用
destroy() {}  過濾器銷燬時調用
                                                            過濾器鏈
doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) {}
 
 
-------------------------------
       Strust2的監聽器
-------------------------------
PreResultListener接口

  void beforeResult(ActionInvocation invocation, String resultCode) {}
監聽的點是當你執行完execute()並返回到顯示頁面以前,beforeResult()方法被執行

--------------
1.
創建包:listener
2.
創建類:MyListener 繼承 PreResultListener
3.
重寫beforeResult方法
public class MyListener implements PreResultListener {
 public void beforeResult(ActionInvocation invocation, String resultCode) {
  
  // resultCode爲 action中業務邏輯方法的返回值
  System.out.println("result=" + resultCode);
 }
}
4.
把監聽器註冊到攔截器中
public class MyInterceptor3 extends MethodFilterInterceptor {
 @Override
 public void init() {
  System.out.println("init3");
 }
 @Override
 public String doIntercept(ActionInvocation invocation) throws Exception {
  //註冊本身定義的監聽器
  invocation. addPreResultListener( new MyListener() );
  System.out.println("intercept()3...");
  String result = invocation.invoke();   System.out.println("finish3...");   return result;  } }
相關文章
相關標籤/搜索