下面我們再來分析另一個攔截器的實現ModelDrivenInterceptor,首先說說他的設計目的,我們知道在Struts中通常有一個ActionFormBean他是用來封裝請求數據的,在WebWork2.x中這一功能得到了進一步的發揮,他可以實現兩中Action驅動模式,他們都是信息攜帶者.
Property-Driven
Model-Driven
最通俗的解釋就是, Property-Driven通過屬性來貫穿整個MVC,而Model-Driven就是通過Model對象來貫穿整個MVC.
他們的存在方式: Model-Drive就是獨立的一個類,而Property-Driven則必須依附於你自定義的Action類
如果我們用Model-Drive方式,那麼就必須在配置文件中添加ModelDrivenInterceptor攔截器,由這個攔截器向我們的Model Bean中傳遞值,且你的Action中 也必須實現ModelDriven接口,用於獲取該Model Bean,下面來看看這個攔截器的具體實現,來做進一步的分析,代碼如下:
public class ModelDrivenInterceptor extends AroundInterceptor {
//~ Methods ////////////////////////////////////////////////////////////////
protected void after(ActionInvocation dispatcher, String result) throws Exception { }
protected void before(ActionInvocation invocation) throws Exception {
Action action = invocation.getAction();
if (action instanceof ModelDriven) {
//判斷該Action是否實現了ModelDriven接口,如果實現了這個ModelDriven接口,他將向這個Action所對應的Model傳遞信息
ModelDriven modelDriven = (ModelDriven) action;
OgnlValueStack stack = invocation.getStack();
// 用於獲取Action中的Model Bean,並壓入OgnlValueStack
stack.push(modelDriven.getModel());
}
}
}
關於OgnlValueStack 的具體信息請參考 http://www.ognl.org
從上面的這個public String intercept(ActionInvocation invocation) 方法中我們可以看出所有的攔截器都是通過ActionInvocation來執行調度的,我們可以稱DefaultActionInvocation為XWork1.x的調度器,說的這裡我想各位對WebWork2.x的攔截器也有了一個大概的了解.
既然DefaultActionInvocation是xWork1.x的調度器,不分析他是說不過去的,接下來我們分析ActionInvocation的實現者DefaultActionInvocation的源碼,已窺其究竟
由於之前也分析過DefaultActionInvocation的一些代碼, 下面則節選部分還沒有分析的代碼來完成簡要的分析
public class DefaultActionInvocation implements ActionInvocation {
//在這裡Result是一個接口,而ActionChainResult是他的一個實現,他的目的是用於處理Action Chain的,在這裡對Action Chain做以下說明:
通常一個Action執行完畢,要麼是返回表單,要麼返回另外一個Action,來繼續執行, 如果返回了Action則就形成了Action Chain 動作鏈,然後繼續執行這個新的Action,直到返回一個non-chain結果
public Result getResult() throws Exception {
Result returnResult = result;
// If we've chained to other Actions, we need to find the last result
while (returnResult instanceof ActionChainResult) {
ActionProxy aProxy = ((ActionChainResult) returnResult).getProxy();
if (aProxy != null) {
Result proxyResult = aProxy.getInvocation().getResult();
if ((proxyResult != null) && (aProxy.getExecuteResult())) {
returnResult = proxyResult;
} else { break; }
} else { break; }
}
return returnResult;
}
//返回Stack
public OgnlValueStack getStack() {
return stack;
}
…
//下面的方法我就不在贅述了,我想大家就是看名稱也應該可以了解一二,如果有什麼疑問,請參考前面的分析
protected void createAction() {
// load action
try {
action = ObjectFactory.getObjectFactory().buildAction(proxy.getConfig());
…
}
protected String invokeAction(Action action, ActionConfig actionConfig) throws Exception {
if (proxy.getConfig().getMethodName() == null) {
return getAction().execute();
…
}
}