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; } }