1. 程式人生 > >面試題:struts 攔截器和過濾器

面試題:struts 攔截器和過濾器

編程 att url face 三種方式 來看 字符 struts 規範

攔截器和過濾器的區別

過濾器是servlet規範中的一部分,任何java web工程都可以使用。

攔截器是struts2框架自己的,只有使用了struts2框架的工程才能用。

過濾器在url-pattern中配置了/*之後,可以對所有要訪問的資源攔截。

攔截器它是只有進入struts2核心內部之後,才會起作用,如果訪問的是jsp,html,css,image或者js是不會進行攔截的。

同時,攔截器還是AOP編程思想的具體體現形式。AOP(Aspect-Oriented Programming)簡單的說就是:

在不修改源碼的基礎上,已有的方法進行動態增強。

在struts2中,攔截器它就是對我們的動作方法進行增強。

(其實就是把重復性的代碼提取出來,然後放到攔截器中,統一管理,統一調用)

1.1.1 攔截器的執行時機

在訪問struts2核心內部時,在動作方法執行之前先正序執行,然後執行動作方法,執行完動作方法和結果視圖之後,再倒序執行。所以它是先進後出,是個棧的結構。

1.1 自定義攔截器

在程序開發過程中,如果需要開發自己的攔截器類,就需要直接或間接的實現com.opensymphony.xwork2.interceptor.Interceptor接口。其定義的代碼如下:

public interface Interceptor extends Serializable {

void init();

void destroy();

String intercept(ActionInvocation invocation) throws Exception;

}

該接口提供了三個方法,其具體介紹如下。

l void init():該方法在攔截器被創建後會立即被調用, 它在攔截器的生命周期內只被調用一次. 可以在該方法中對相關資源進行必要的初始化。

l void destroy():該方法與init方法相對應,在攔截器實例被銷毀之前,將調用該方法來釋放和攔截器相關的資源。它在攔截器的生命周期內,也只被調用一次。

l String intercept(ActionInvocation invocation) throws Exception:該方法是攔截器的核心方法,用來添加真正執行攔截工作的代碼,實現具體的攔截操作。它返回一個字符串作為邏輯視圖,系統根據返回的字符串跳轉到對應的視圖資源。每攔截一個動作請求

, 該方法就會被調用一次。該方法的ActionInvocation參數包含了被攔截的Action的引用,可以通過該參數的invoke()方法,將控制權轉給下一個攔截器或者轉給Actionexecute()方法。

如果需要自定義攔截器,只需要實現Interceptor接口的三個方法即可。然而在實際開發過程中,除了實現Interceptor接口可以自定義攔截器外,更常用的一種方式是繼承抽象攔截器類AbstractIntercepter。該類實現了Interceptor接口,並且提供了init()方法和destroy()方法的空實現。使用時,可以直接繼承該抽象類,而不用實現那些不必要的方法。攔截器類AbstractInterceptor中定義的方法如下所示:

public abstract class AbstractInterceptor implements Interceptor {

public void init() {}

public void destroy() {}

public abstract String intercept(ActionInvocation invocation)

throws Exception;

}

從上述代碼中可以看出,AbstractInterceptor類已經實現了Interceptor接口的所有方法,一般情況下,只需繼承AbstractInterceptor類,實現interceptor()方法就可以創建自定義攔截器。

只有當自定義的攔截器需要打開系統資源時,才需要覆蓋AbstractInterceptor類的init()方法和destroy()方法。與實現Interceptor接口相比,繼承AbstractInterceptor類的方法更為簡單。

當然還有更簡單的,AbstractInterceptor還有一個子類,MethodFilterInterceptor,該類中提供了兩個屬性,可以告知攔截器對哪些方法進行攔截或者對哪些方法排除。

下圖展示的就是攔截器的類結構視圖:

1.1.1 自定義步驟

通過在攔截器類視圖上我們可以得知,我們定義攔截器可以有三種辦法:

第一種:定義一個類,實現Interceptor接口

第二種:定義一個類,繼承AbstractInterceptor

第三種:定義一個類,繼承MethodFilterInterceptor

在這三種方式中,我們選擇第二種和第三種都可以。那麽後兩種有什麽區別呢?

我們來看看AbstractorInteractor類中的代碼:

我們再來看看MethodFilterInterceptor中的代碼:

看完兩個類之後,我們有了結論。即:選擇第三種方式,比第二種多了一個功能,就是告知攔截器哪些方法我們需要攔截,哪些方法我們不需要攔截。(註意:不要想著很傻的問題,在需要攔截和不需要攔截的屬性中提供同一個方法

根據以上的內容,我們開始編寫我們自己的攔截器。

面試題:struts 攔截器和過濾器