背景:
在使用struts時(shí)我們經(jīng)常會(huì)用到DispatchAction.有了這個(gè)類,我們不需要針對(duì)每一個(gè)Action都要寫一個(gè)特定的類,而是可以把一些相關(guān)的方法放到一個(gè)類中.
DispatchActon中使用了reflection來(lái)根據(jù)你傳入的method參數(shù)的值來(lái)獲取相應(yīng)的參數(shù)來(lái)處理你的請(qǐng)求.正如他的方法 -- 他根據(jù)你傳入的請(qǐng)求參數(shù),用不同的方法來(lái)處理你的請(qǐng)求.
但是,通常我們還會(huì)遇到另一種情況,如果我想在之行實(shí)際的action處理方法之前或者之后再去做一些別的事情而又不想修改我們實(shí)際存在的action類呢?這里我將介紹一種方法.
只要看看struts中DispatchAction(以下簡(jiǎn)寫做DA)的源文件你就會(huì)發(fā)現(xiàn),它有一個(gè)dispatchMethod方法,接受5個(gè)參數(shù).其中4個(gè)就是我們通常的struts action里的(mapping,request,response,form),還有一個(gè)參數(shù)就是指定方法的參數(shù)的名字.
protected ActionForward dispatchMethod(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response, String name) throws Exception
其實(shí)現(xiàn)方法如下:
// Make sure we have a valid method name to call.
// This may be null if the user hacks the query string.
if (name == null) {
return this.unspecified(mapping, form, request, response);
}
// Identify the method object to be dispatched to
Method method = null;
try {
method = getMethod(name);
} catch (NoSuchMethodException e) {
String message = messages.getMessage("dispatch.method", mapping
.getPath(), name);
log.error(message, e);
throw e;
}
ActionForward forward = null;
try {
Object args[] = { mapping, form, request, response };
//特殊的url不進(jìn)行處理(add)
String actionUrl = request.getServletPath(); // "/rolesign.do"
boolean exception = isException(actionUrl);
if(exception) {
logger.debug("requestUrl :"+actionUrl+",no pre and post process");
}
// 預(yù)處理(add)
if (!disabled && !exception) {
logger.debug("preProcess begin");
preProcess(request);
logger.debug("preProcess end");
}
forward = (ActionForward) method.invoke(this, args);
// 后處理(add)
if (!disabled && !exception ){
logger.debug("postProcess begin");
postProcess(request);
logger.debug("postProcess end");
}
} catch (ClassCastException e) {
String message = messages.getMessage("dispatch.return", mapping
.getPath(), name);
log.error(message, e);
throw e;
} catch (IllegalAccessException e) {
String message = messages.getMessage("dispatch.error", mapping
.getPath(), name);
log.error(message, e);
throw e;
} catch (InvocationTargetException e) {
// Rethrow the target exception if possible so that the
// exception handling machinery can deal with it
Throwable t = e.getTargetException();
if (t instanceof Exception) {
throw ((Exception) t);
} else {
String message = messages.getMessage("dispatch.error", mapping
.getPath(), name);
log.error(message, e);
throw new ServletException(t);
}
}
// Return the returned ActionForward instance
return (forward);
大部分代碼還是從DA的實(shí)現(xiàn)方法中copy過(guò)來(lái),但是我在這里加入了3個(gè)地方.分別是:
1.對(duì)請(qǐng)求url的識(shí)別,確定是否使用預(yù)/后處理
2.預(yù)處理方法調(diào)用
3.后處理方法調(diào)用
當(dāng)然你要自己寫預(yù)處理方法和后處理方法.這里你可以傳任意你想要的參數(shù)給request,然后通過(guò)reflection來(lái)動(dòng)態(tài)調(diào)用任意的java方法,比如你可以在頁(yè)面設(shè)置一個(gè)preFunction參數(shù),它的值是classname.methodname.然后你可以在preProcess的實(shí)現(xiàn)中通過(guò)reflection來(lái)查找這個(gè)方法并執(zhí)行.
如果你想讓項(xiàng)目中所有的action都有這種特性,則只要讓根Action繼承DA并覆蓋它的dispatchMethod方法即可.
這是在實(shí)際項(xiàng)目中用到的一個(gè)特性,為了盡可能少的修改原有的代碼使用了這種折中的做法.使用reflection時(shí)建議不要執(zhí)行太過(guò)復(fù)雜的方法,可能會(huì)使你的action響應(yīng)慢的.
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。