WebWork
教程
- Interceptor(
攔截器
)
Interceptor
(攔截器)將
Action
共用的行為獨立出來,在
Action
執行前后運行。這也就是我們所說的
AOP
(
Aspect Oriented Programming
,面向切面編程),它是分散關注的編程方法,它將通用需求功能從不相關類之中分離出來;同時,能夠使得很多類共享一個行為,一旦行為發生變化,不必修改很多類,只要修改這個行為就可以。
Interceptor
將很多功能從我們的
Action
中獨立出來,大量減少了我們
Action
的代碼,獨立出來的行為具有很好的重用性。
XWork
、
WebWork
的許多功能都是有
Interceptor
實現,可以在配置文件中組裝
Action
用到的
Interceptor
,它會按照你指定的順序,在
Action
執行前后運行。
Interceptor
在框架中的應用如下圖所示
當你提交對
Aciton
(默認是
.action
結尾的
Url
)的請求時,
ServletDispatcher
會根據你的請求,去調度并執行相應的
Action
。在
Action
執行之前,調用被
Interceptor
截取,
Interceptor
在
Action
執行前后運行。
我們在用戶注冊的例子中就使用了取得
Request
請求參數的攔截器,配置文件中
<interceptor-ref name="params"/>
將攔截器
params
組裝到
RegisterAction
中。“
params
”在我們的
webwork-default.xml
配置文件中有定義,
webwork-default.xml
中攔截器的定義如下:
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/>
<interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
<interceptor name="model-driven" class="com.opensymphony.xwork.interceptor.ModelDrivenInterceptor"/>
<interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>
<interceptor name="token" class="com.opensymphony.webwork.interceptor.TokenInterceptor"/>
<interceptor name="token-session" class="com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor"/>
<interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/>
<interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/>
<interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/>
<interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/>
<interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/>
<interceptor-stack name="defaultStack">
<interceptor-ref name="static-params"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
</interceptor-stack>
<interceptor-stack name="validationWorkflowStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="validation"/>
<interceptor-ref name="workflow"/>
</interceptor-stack>
</interceptors>
這些都時有框架提供的默認的
Interceptor
,下面我來看看
Interceptor
使用的步驟:
1、
創建一個自己需要的
Interceptor
類,它必需實現
com.opensymphony.xwork.interceptor.Interceptor
接口,具體的開發見下面的
Interceptor
的原理。
2、
在配置文件(
xwork..xml
)中申明這個
Interceptor
類,它放在標簽
<interceptor />
中,同是
<interceptor />
標簽嵌入在
<interceptors />
標簽內部。
3、
創建
Interceptor
棧,使用標簽:
<interceptor-stack />
,
讓一組
Interceptor
可以按次序調用。(可選)
4、
指定
Action
所要用到的
Interceptor
(前面申明過的),可以用
<interceptor-ref />
或
<default-interceptor-ref />
標簽。前面的標簽指定某個
Action
所用到的
Interceptor
,如果
Action
沒有被用
<interceptor-ref />
指定
Interceptor
,它將使用
<default-interceptor-ref />
指定的
Interceptor
。
框架中給我們提供了很多實用的
Interceptor
,它的定義上面已經給出,它的具體功能如下:
l
timer
:記錄
Action
執行的時間,并做為日志信息輸出;
l
logger
:在日志信息中輸出要執行的
Action
信息;
l
chain
:將前一個執行結束的
Action
屬性設置到當前的
Action
中。它被用在
ResultType
為“
chain
”指定結果的
Action
中,該結果
Action
對象會從
OgnlValueStack
中獲得前一個
Action
對應的屬性,它實現
Action
鏈之間的數據傳遞;
l
static-params
:將
xwork.xml
配置文件里定義的
Action
參數,設置到對應的
Action
中。
Action
參數使用
<param />
標簽,是
<action />
標簽的直接子元素。我們這里定義的
Action
類必需實現
com.opensymphony.xwork.config.entities
. Parameterizable
接口;
l
params
:將
Request
請求的參數設置到相應
Action
對象的屬性中,用戶注冊例子用到過這個攔截器;
l
model-driven
:如果
Action
實現
ModelDriven
接口,它將
getModel()
取得的模型對象存入
OgnlValueStack
中;
l
component
:激活組件功能支持,讓注冊過的組件在當前
Action
中可用,即為
Action
提供
IoC
(依賴倒轉控制)框架的支持;
l
token
:核對當前
Action
請求(
request
)的有效標識,防止重復提交
Action
請求
(request)
。
l
token-session
:功能同上,但是當提交無效的
Action
請求標識時,它會將請求數據保存到
session
中。
l
validation
:實現使用
xml
配置文件(
{Action}-validation.xml
)對
Action
屬性值進行驗證,詳細請看后面介紹的驗證框架。
l
workflow
:調用
Action
類的驗證功能,假設
Action
使用
ValidationAware
實現驗證(
ActionSupport
提供此功能),如果驗證沒有通過,
workflow
會將請求返回到
input
視圖(
Action
的
<result />
中定義的)。
l
servlet-config
:提供
Action
直接對
HttpServletRequest
或
HttpServletResponse
等
JavaServlet api
的訪問,
Action
要實現相應的接口,例如:
ServletRequestAware
或
ServletResponseAware
等
。如果必需要提供對
JavaServlet api
的訪問,我們建議使用
ServletActionContext
,在前面
ActionContext
章節中有介紹。
l
prepare
:在
Action
執行之前調用
Action
的
prepare()
方法,這個方法是用來準備
Action
執行之前要做的工作。它要求我們的
Action
必需實現
com.opensymphony.xwork
. Preparable
接口
conversionError
:用來處理框架進行類型轉化
(Type Conversion)
時的出錯信息。它將存儲在
ActionContext
中的類型轉化(
Type Conversion
)錯誤信息轉化成相應的
Action
字段的錯誤信息,保存在堆棧中。根據需要,可以將這些錯誤信息在視圖中顯示出來。
下面我們來看看
Interceptor
是如何實現在
Action
執行前后調用的:
Action
和
Interceptor
在框架中的執行,是由
ActionInvocation
對象調用的。它是用方法:
String invoke() throws Exception;
來實現的,它首先會依次調用
Action
對應的
Interceptor
,執行完成所有的
Interceptor
之后,再去調用
Action
的方法,代碼如下:
if
(interceptors.hasNext()) {
Interceptor interceptor = (Interceptor) interceptors.next();
resultCode = interceptor.intercept(this);
} else {
if (proxy.getConfig().getMethodName() == null) {
resultCode = getAction().execute();
} else {
resultCode = invokeAction(getAction(), proxy.getConfig());
}
}
它會在攔截器棧中遍歷
Interceptor
,調用
Interceptor
的
方法:
String intercept(ActionInvocation invocation) throws Exception;
。
我們一直都提到,
Interceptor
是在
Action
前后執行,可是從上面的代碼我們看到的卻是執行完所有
Interceptor
的
intercept
()
方法之后再去調用我們的
Action
。“在
Action
前后執行”是如何實現的呢?我們來看看抽象類
AroundInterceptor
的
intercept
()
實現:
public
String intercept(ActionInvocation invocation) throws Exception {
String result = null;
before(invocation);
result = invocation.invoke();
after(invocation, result);
return result;
}
原來在
intercept
()
方法又對
ActionInvocation
的
invoke()
方法進行遞歸調用,
ActionInvocation
循環嵌套在
intercept
()
中,一直到語句
result = invocation.invoke();
執行結束,即:
Action
執行完并返回結果
result
,這時
Interceptor
對象會按照剛開始執行的逆向順序依次執行結束。這樣
before
()
方法將在
Action
執行前調用,
after
()
方法在
Action
執行之后運行
posted on 2006-12-14 19:16
周銳 閱讀(649)
評論(0) 編輯 收藏 所屬分類:
Webwork