Struts 2攔截器
代理模式
抽象主題:真是主題和代理主題的共同接口
真實主題:實現抽象主題,定義了代理角色所代表的真實對象
代理主題:實現抽象主題,含有對真實主題角色的引用,代理角色通常將會在客戶端調用傳遞給真實主題對象之前或者之後執行的某些操作,而不是單純返回真實對象。
動態代理模式
1. 創建抽象主題接口
2. 創建真實主題類實現抽象主題接口
3. 新建處理類,實現java.lang.reflect.InvocationHandler接口
4. Client類,該類中new一個真實主題對象並傳入處理類中
5. 最後用JDK自帶的Proxy類的newProxyInstance方法,創建動態代理實例。
攔截器的實現原理
攔截器:在進行一個操作(調用某個方法)時,它會在執行操作前進行一些列的操作,而在執行完操作後,它又會進行一系列操作。
攔截:其實是動態地生成一個代理對象,而這個代理對象包含對攔截器方法的調用。因此調用代理對象的方法的同時也調用攔截器方法,這樣就實現了動態的調用攔截器方法。
舉例:
1. 新建DAO接口,因爲動態代理只能對實現了接口的實例來生成代理。定義相應的方法。
2. DAO接口實現類,實現DAO接口的所有方法。
3. 攔截器類
4. 處理類,實現java.lang.reflect.InvocationHandler接口,方法中以適當的順序調用DAOImpl類和攔截器類的方法。
5. 代理工廠類,該工廠接受目標代理對象,創建一個處理類對象,目標代理對象傳入處理類對象,最後用java.lang.reflect.Proxy創建並返回代理對象實例。
6. Client類,調用代理
自定義攔截器
第一種自定義攔截器的方法:
實現com.opensymphony.xwork2.interceptor.Interceptor接口
實現其intercept方法尤爲重要,可以在該方法裏定義各種動作。
package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import java.io.Serializable;
public interface Interceptor extends Serializable{ void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception; } |
第二種自定義攔截器方法:
繼承com.opensymphony.xwork2.interceptor.AbstractInterceptor類
該類實現了上述的Interceptor接口。
自定義好攔截器後要進行配置:
配置攔截器
在struts.xml中添加<interceptors>標籤,是<package>的子標籤:
<interceptors> <interceptor name=”攔截器名” class=”攔截器實現類”></interceptor> </interceptors> |
如果需要傳參:
<interceptors> <interceptor name=”攔截器名” class=”攔截器實現類”> <param name=”參數名”>參數值</param> </interceptor> </interceptors> |
如果需要配置多個攔截器,就多添加<interceptor>,還可以把多個攔截器組合起來組成攔截器棧。
<interceptors> <interceptor name=”攔截器名” class=”攔截器實現類”> <param name=”參數名”>參數值</param> </interceptor>
<interceptor-stack name=”攔截器棧名”> <interceptor name=”攔截器一” class=”攔截器實現類”> <param name=”參數名”>參數值</param> </interceptor> <interceptor name=”攔截器二” class=”攔截器實現類”></interceptor> </interceptor-stack>
</interceptors> |
按上面的方法配置好攔截器後,還要
配置Action使用攔截器:struts.xmls在<action>標籤中添加子標籤:
<interceptor-ref name=”myInter”></interceptor-ref>
<interceptor-ref name=”myInter”>
<param name=”myValue”>abcd</param>
</interceptor-ref>
這就完成了攔截器的創建,配置和使用。按以上步驟完成後發現原來的輸入校驗功能沒有了,數據格式不對的話直接跳到了登陸失敗頁面,而數據格式對了也是登錄失敗。原因如下:
配置Action時,package是繼承struts-default包的,而這個struts-default包配置了默認的攔截器棧defaultStack,這個棧中定義了大量的攔截器。Struts 2中的類型轉換,輸入校驗和文件上傳等操作都是通過調用這些隱含配置的攔截器。
如果struts.xml的package包中的Action沒有添加使用攔截器,則默認的攔截器將會起作用。而一旦該包中的Action添加使用了某個攔截器,那麼默認的攔截器就相當於沒有添加,所以沒有作用。這時需要在<action>中手動添加子標籤來配置這個defaultStack:
<interceptor-ref name=”defaultStack”></interceptor-ref>
這樣就一切OK啦!