前一篇博客中根据Struts2的官方架构图简单的描绘了Struts2运行流程,并解释了一下Struts2中一些核心类的用途。现在我们从源码的角度分析Struts2的核心流程。
首先根据一个Struts2的HelloWorld绘制出Struts2的启动时的时序图:
备注:由于这个图非常大,所以这里放置了一个缩图。文章的最后我会给出这个时序图的下载地址。
把核心流程分为16步。接下来一步步的分析:
一.请求URL时执行StrutsPrepareAndExecuteFilter的doFilter()
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);
} else {
prepare.setEncodingAndLocale(request, response);
prepare.createActionContext(request, response);
prepare.assignDispatcherToThread();
request = prepare.wrapRequest(request);
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) {
boolean handled = execute.executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
} else {
execute.executeAction(request, response, mapping);
}
}
} finally {
prepare.cleanupRequest(request);
}
}
二.执行PrepareOperations的setEncodingAndLocale设置编码
prepare.setEncodingAndLocale(request, response);
PrepareOperations中调用Dispatcher中的prepare()方法
public void setEncodingAndLocale(HttpServletRequest request, HttpServletResponse response) {
dispatcher.prepare(request, response);
}
在Dispatcher中的prepare中则通过依赖注入在default.properties中的定义的STRUTS_I18N_ENCODING
public void prepare(HttpServletRequest request, HttpServletResponse response) {
String encoding = null;
if (defaultEncoding != null) {
encoding = defaultEncoding;
}
// check for Ajax request to use UTF-8 encoding strictly http://www.w3.org/TR/XMLHttpRequest/#the-send-method
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
encoding = "UTF-8";
}
Locale locale = null;
if (defaultLocale != null) {
locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
}
if (encoding != null) {
applyEncoding(request, encoding);
}
if (locale != null) {
response.setLocale(locale);
}
if (paramsWorkaroundEnabled) {
request.getParameter("foo"); // simply read any parameter (existing or not) to "prime" the request
}
}