public void process(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// 处理 contentType 为 multipart/form-data 的 POST 请求,如果是则将请求包装,否则,返回原有
//请求,一般来说,除非是要处理文件上传,否则不用关心
request = processMultipart(request);
//取得 URI 路径
String path = processPath(request, response);
if (path == null) {
return;
}
if (log.isDebugEnabled()) {
log.debug("Processing a '" + request.getMethod() +
"' for path '" + path + "'");
}
// 处理一些国际化的事务
processLocale(request, response);
// 决定请求的Content编码方式。指定响应结果内容类型和字符编码,默认是text/html
processContent(request, response);
//nochache如果是true在响应结果中加入特定的头参数
processNoCache(request, response);
// /前置处理,默认返回 true,子类可以重新定义它以決定要不要继续处理
if (!processPreprocess(request, response)) {
return;
}
this.processCachedMessages(request, response);
//根据客户请求信息的path来决定是否返回ActionMapping实例。
//如果不能找到path的映射则先看是否actionMapping中有unknown属性 有返回,没有这客户将会得到一个error响应
ActionMapping mapping = processMapping(request, response, path);
if (mapping == null) {
return;
}
// Check for any role required to perform this action
if (!processRoles(request, response, mapping)) {
return;
}
// 处理ActionForm,如果沒有就新增一个,之后一直使用它
//首先先检查是否存在ActionMapping配置的ActionForm。如果存在,
//则在有效区域查找是否存在该ActionForm实例,存在则复用,不存在则创建一个实例
//然后将实例保存在配置文件中的有效域(request,session)内,
//并用mapping.getAttribute()作key值
ActionForm form = processActionForm(request, response, mapping);
// 如果存在ActionMapping配置的ActionForm,则封装请求对象的数据
//到ActionForm中,在封装之前,先调用ActionForm的reset()方法进行属性值的默认化
processPopulate(request, response, form, mapping);
// 如果ActionForm被配置好,并且action元素的属性Validate被设置为true,
//则进一步调用validate()方法进行规则校验。如果validate()方法校验失败,
//就会保存一个ActionErrors对象到请求域中,请求将自动重定向到action映射的
//input属性所指向的页面中。如果校验通过或action映射中没有配置ActionForm,
//则继续处理请求
try {
if (!processValidate(request, response, form, mapping)) {
return;
}
} catch (InvalidCancelException e) {
ActionForward forward = processException(request, response, e, form, mapping);
processForwardConfig(request, response, forward);
return;
} catch (IOException e) {
throw e;
} catch (ServletException e) {
throw e;
}
// 判断 <action> 标签的 forward 或 include 标签是不是被设定
// 这两个标签在设定一個路径,其与 type 属性是互斥的,当设定
// 其中一个属性时,调用 RequestDispatcher 的 forward() 或
// include() ,其作用与设定ForwardAction或IncludeAction相同
// 直接传送而不再使用Action物件进行接下来的处理
if (!processForward(request, response, mapping)) {
return;
}
if (!processInclude(request, response, mapping)) {
return;
}
//创建或获得action实例来处理此请求
// 处理action,如果沒有就生成一个,之后一直使用它
Action action = processActionCreate(request, response, mapping);
if (action == null) {
return;
}
// 调用Action的execute()方法,并反回ActionForward
ActionForward forward =
processActionPerform(request, response,
action, form, mapping);
//处理返回来的ActionForward
processForwardConfig(request, response, forward);
}