看DispatchAction的代码(仅部分主要代码):
public abstract class DispatchAction extends Action{
protected static String prefix = "do";
protected static String init = "init";
protected Map methods = new HashMap();
protected Class types[] = {};
public final ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception {
String parameter = mapping.getParameter();
if (parameter == null) {
String message =messages.getMessage("dispatch.handler", mapping.getPath());
log.error(message);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
message);
return (null);
}
ActionContext.init(mapping, form, request, response);
String name = request.getParameter(parameter);
return dispatchMethod(name);
}
protected ActionForward dispatchMethod(String name) throws Exception {
if (StringUtil.isNull(name)) {
name = init;
runRecycle();
}
Method method = null;
try {
method = getMethod(name);
} catch (NoSuchMethodException e) {
String message =
messages.getMessage("dispatch.method", getPath(), name);
log.error(message, e);
sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
return (null);
}
ActionForward forward = null;
try {
forward = (ActionForward) method.invoke(this, new Object[]{});
} catch (Exception e) {
//这里是异常处理,节省空间,略去
return (null);
}
return (forward);
}
//利用反射,得到将要执行的方法
protected Method getMethod(String name) throws NoSuchMethodException {
synchronized (methods) {
Method method = (Method) methods.get(name);
if (method == null) {
method = clazz.getMethod(getMethodName(name), types);
methods.put(name, method);
}
return (method);
}
}
//将传递过来的方法名改写成要求的方法名,例如将save变为doSave
protected String getMethodName(String name) {
return prefix + name.substring(0, 1).toUpperCase() + name.substring(1);
}
}
说明:上面代码已经很清晰了,因为继承的Struts的Action类,那么继承类会默认执行里面的execute方法,而在次方法里,将传递到execute里的参数数据,如果ActionForm,ActionMapping等利用ThreadLocal保存起来,并将指定的方法名经过处理后,利用反射调用action里的方法执行,不过似乎上面代码没有ThreadLocal,但是你可能注意到这一句:
ActionContext.init(mapping, form, request, response);
,对了,就是在这个类里,我们使用ThreadLocal将这些参数变量保存起来,并在线程的整个周期里传递。