【Struts2】:自定義Interceptor

連江偉發表於2016-05-17

        雖然Struts2框架提供了許多的攔截器,並且這些內建的攔截器實現了Struts2的大部分功能,因此,大部分的Web應用的通用功能,都可以通過直接使用這些攔截器來完成,但是還是有一些系統邏輯相關的通用功能,可以通過自定義攔截器來實現。值得一提的是,Struts2的攔截器機制非常的簡單好用。


        我們想要開發自己的攔截器類,通常有兩種方式,一個是實現Interceptor介面,另一個是繼承AbstractInterceptot類,相比較而言,通過繼承AbstractInterceptor類來實現自定義攔截器更加的簡單。


方式1:實現Interceptor介面


        先來看看該介面的定義,程式碼如下:

public interface Interceptor extends Serializable {

    /**
     * Called to let an interceptor clean up any resources it has allocated.
     */
    void destroy();

    /**
     * Called after an interceptor is created, but before any requests are processed using
     * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving
     * the Interceptor a chance to initialize any needed resources.
     */
    void init();

    /**
     * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the
     * request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code.
     *
     * @param invocation the action invocation
     * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself.
     * @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}.
     */
    String intercept(ActionInvocation invocation) throws Exception;

}

        通過上面的介面可以看出,該介面裡包含了三個方法。


        init():在攔截器被例項化之後,在該攔截器執行攔截之前,系統將回撥該方法。對於每個攔截器而言,其init()方法只執行一次。因此該方法的方法體主要用於初始化各種資源,比如資料庫連線等。


        destroy():該方法與init()方法對應。在攔截器例項被銷燬之前,系統將回撥該攔截器的destroy方法,該方法用於銷燬在init方法裡開啟的資源。


        intercept(ActionInvocation invocation):該方法是使用者需要實現的攔截動作。就像Action的execute()方法一樣,intercept方法會返回一個字串作為邏輯檢視。如果該方法直接返回了一個字串,系統將會跳轉到該邏輯檢視對應的實際檢視資源,不會呼叫被攔截的Action。該方法的ActionInvocation引數包含了被攔截的Action的引用,可以通過呼叫該引數的invoke方法,將控制權轉交給下一個攔截器,或者轉給Action的execute方法。


方式2:繼承AbstractInterceptor抽象類


        我們可以開啟原始碼檢視一下這個類的程式碼是如何定義的。

public abstract class AbstractInterceptor implements Interceptor {

    /**
     * Does nothing
     */
    public void init() {
    }
    
    /**
     * Does nothing
     */
    public void destroy() {
    }


    /**
     * Override to handle interception
     */
    public abstract String intercept(ActionInvocation invocation) throws Exception;
}

        從原始碼中我們可以看到,其實AbstractInerceptor實現了Interceptor介面,同樣具有三個方法,當然這三個方法是實現自Interceptor介面,只不過init和destroy方法都是空實現,如果我們實現的攔截器不需要開啟資源,則可以無須實現這兩個方法,從這個角度講,繼承AbstractInterceptor類來實現自定義攔截器會更加的簡單方便。


        下面我簡單寫一個攔截器,來說明如何實現自定義攔截器,鑑於上面的兩種方式其本質是一樣的,都是實現了Interceptor介面,因此我就第二種方式為例,給出程式碼示例,如下:

public class SimpleInterceptor
	extends AbstractInterceptor
{
	// 簡單攔截器的名字
	private String name;
	// 為該簡單攔截器設定名字的setter方法
	public void setName(String name)
	{
		this.name = name;
	}
	public String intercept(ActionInvocation invocation)
		throws Exception
	{
		// 取得被攔截的Action例項
		LoginAction action = (LoginAction)invocation.getAction();
		// 列印執行開始的時間
		System.out.println(name + " 攔截器的動作---------" +
			"開始執行登入Action的時間為:" + new Date());
		// 取得開始執行Action的時間
		long start = System.currentTimeMillis();
		// 執行該攔截器的後一個攔截器
		// 如果該攔截器後沒有其他攔截器,則直接執行Action的被攔截方法
		String result = invocation.invoke();
		// 列印執行結束的時間
		System.out.println(name + " 攔截器的動作---------" +
			"執行完登入Action的時間為:" + new Date());
		long end = System.currentTimeMillis();
		System.out.println(name + " 攔截器的動作---------" +
			"執行完該Action的時間為" + (end - start) + "毫秒");
		return result;
	}
}

小結一下:


        綜上所述,我們知道了在Struts2的框架之下,想要自定義攔截器,以滿足我們的業務需求,簡直是非常的easy,但是寫完我們自定義的攔截器還沒完,還需要配置和使用,否則你寫的攔截器是不起作用的,關於如何配置和使用攔截器,且聽我下回分解。

相關文章