WebWork截獲Action請(qǐng)求,在Action執(zhí)行之前或之后調(diào)用攔截器方法。這樣,可以用插拔的方式將功能注入Action中。WebWork框架的很多功能都是以攔截器的形式提供出來(lái)。例如:參數(shù)組裝,驗(yàn)證,國(guó)際化,文件上傳等等。

1. 一個(gè)攔截器就是在xwork.xml文件中定義的一個(gè)無(wú)狀態(tài)Java類(lèi),它至少要實(shí)現(xiàn)XWork的com.opensymphony.xwork.interceptor.Interceptor接口。代碼如下:

public interface Interceptor extends Serializable {

void destroy();

void init();

String intercept(ActionInvocation invocation) throws Exception;

}

2. 實(shí)現(xiàn)Interceptor接口的攔截器,代碼部分在intercept方法中實(shí)現(xiàn)。在intercept方法中,可以直接返回一個(gè)Result字符串,這樣整個(gè)執(zhí)行直接“短路”,這時(shí)Action的execute方法也不會(huì)執(zhí)行(一般很少會(huì)這么用)。所以,一般都會(huì)在這個(gè)方法里調(diào)用參數(shù)對(duì)象invocation的invoke方法,并返回這個(gè)方法執(zhí)行的結(jié)果。這樣會(huì)持續(xù)執(zhí)行后面的攔截器方法以及Action的execute方法等。

3. 大部分的時(shí)候,攔截器直接繼承WebWork的抽象類(lèi) com.opensymphony.xwork.interceptor.AroundInterceptor就可以了。這時(shí),需要實(shí)現(xiàn)它的before 和after方法。Before方法會(huì)在Action執(zhí)行之前調(diào)用,after方法在Action執(zhí)行之后調(diào)用。

4. 攔截器的執(zhí)行順序。我們可將多個(gè)攔截器放一起組裝成一個(gè)攔截器棧。這樣攔截器會(huì)按照棧的順序由上而下執(zhí)行before方法,所有before方法執(zhí)行結(jié)束,再執(zhí)行Action的方法,執(zhí)行Result的方法,再返回執(zhí)行結(jié)果,最后再?gòu)南露蠄?zhí)行攔截器的after方法


5. 攔截器的過(guò)濾功能。我們通常會(huì)在應(yīng)用中使用一個(gè)通用的定義多個(gè)攔截器的攔截器棧。但有些Action方法在調(diào)用的時(shí)候,不需要要其中的部分?jǐn)r截器。這時(shí),我們就可以使用攔截器過(guò)濾功能。如果攔截器要擁有過(guò)濾功能,必須實(shí)現(xiàn)抽象類(lèi) com.opensymphony.xwork.interceptor.MethodFilterInterceptor。這樣,攔截器在定義的時(shí)候或者在Action引用攔截器棧的時(shí)候,我們就可以指定哪些Action方法是需要過(guò)濾的,哪些Action是不需要過(guò)濾的。
  攔截器可以將任意代碼包含在調(diào)用棧中活動(dòng)執(zhí)行前或之后, 它可以極大的簡(jiǎn)化代碼同時(shí)提供增強(qiáng)代碼復(fù)用能力. XWork和WebWork的許多特性多作為攔截器實(shí)現(xiàn), 可以和你自己的攔截器一起通過(guò)外部配置任意指定順序并配置在任意活動(dòng)上.
  換言之, 當(dāng)你訪問(wèn)一個(gè)*.action的地址, WebWork的 class="monospaced">ServletDispatcher執(zhí)行一個(gè)活動(dòng)調(diào)用. 在活動(dòng)執(zhí)行前, 這一調(diào)用可以被另一個(gè)對(duì)象截取, 這個(gè)對(duì)象就稱為攔截器. 要想在一個(gè)活動(dòng)執(zhí)行之前(或之后)設(shè)置一個(gè)攔截器, 只需正確配置xwork.xml, 如下例所示:

攔截器配置:
<action name="formProcessing" class="lesson04_01_01.FormProcessingAction">
<result name="input" type="dispatcher">ex01-index.jsp</result>
<result name="success" type="dispatcher">ex01-success.jsp</result>
<interceptor-ref name="validationWorkflowStack" />
</action>
  名為formProcessing的Action使用了validationWorkflowStack. 它是一個(gè)截取器棧, 棧中按照截取器的執(zhí)行順序進(jìn)行組織. 這個(gè)截取器棧定義在webwork-default.xml, 這樣我們需要做的就是在活動(dòng)配置的<interceptor-ref />或包配置中的<default-interceptor-ref />中聲明, 就像:

攔截器配置:
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-1.0.dtd">


<xwork>
<!-- Include webwork defaults (from WebWork JAR). -->
<include file="webwork-default.xml" />

<!-- Configuration for the default package. -->
<package name="default" extends="webwork-default">
<!-- Default interceptor stack. -->
<default-interceptor-ref name="defaultStack" />

<!-- Action: HelloWebWorldAction. -->
<action name="helloWebWorld" class="lesson03.HelloWebWorldAction">
<result name="success" type="dispatcher">ex01-success.jsp</result>
</action>
</package>
</xwork>

-------------------------------------------------------
寫(xiě)個(gè)示例,實(shí)現(xiàn)在interceptor中判斷當(dāng)前時(shí)間,返回問(wèn)候語(yǔ)句,比如“Good afternoon”
1.xwork_interceptor.xml
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">

<xwork>

<package name="hello1" extends="webwork-default">
<!-- 在action和result code之間建立了聯(lián)系-->
<interceptors>
<interceptor name="greetingInterceptor" class="com.vstsoft.action.GreetingInterceptor" />
</interceptors>
<action name="greeting" class="com.vstsoft.action.GreetingAction">
<interceptor-ref name="greetingInterceptor" />
<result name="success">/success.jsp</result>
<result name="input">/error.jsp</result>
</action>
</package>
</xwork>
2.GreetingAction
package com.vstsoft.action;

import com.opensymphony.xwork.Action;

public class GreetingAction implements Action {

public String execute(){
// TODO Auto-generated method stub
for(int i=0;i<10;i++){
System.out.println(i);
}
return SUCCESS;//INPUT對(duì)應(yīng)于xwork.xml中的resultcode='success'
}

}
3.GreetingInterceptor
package com.vstsoft.action;

import java.util.Calendar;
import com.opensymphony.xwork.interceptor.Interceptor;
import com.opensymphony.xwork.ActionInvocation;

public class GreetingInterceptor implements Interceptor {
public void init() { }
public void destroy() { }
public String intercept(ActionInvocation invocation) throws Exception {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
String greeting = (hour < 6) ? "Good evening" :
((hour < 12) ? "Good morning":
((hour < 18) ? "Good afternoon": "Good evening"));

invocation.getInvocationContext().getSession().put("greeting", greeting);

String result = invocation.invoke();

return result;
}
}
4.success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="ww" uri="/webwork"%>
<%String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>


<html>
<head>
<title>Say Hello</title>
</head>
<body>
<font color="red"><%=session.getAttribute("greeting")%></red>
</body>
</html>