启动struts2需要在web.xml中配置一个过滤器:
<filter> <filter-name>action</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>action</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
当用户从浏览器发送一个请求到服务器时,首先会经过该过滤器:StrutsPrepareAndExecuteFilter
//初始化,主要是实例化prepare和execute已及dispathcher
public void init(FilterConfig filterConfig) throws ServletException {
.
.
dispatcher = init.initDispatcher(config);
prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);//
execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
postInit(dispatcher, filterConfig);//该方法为空,主要是留给开发人员拓展用
.
.
}
//
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
//如果用户请求不到达action则直接放行
if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);
} else {
prepare.setEncodingAndLocale(request, response);
prepare.createActionContext(request, response);//创建 actioncontext
prepare.assignDispatcherToThread();//把actioncontext放到threadlocal本地线程中去
request = prepare.wrapRequest(request);
//创建actionMapper主要包括一些请求转发信息,它首先会去当期request请求中去找
//如果找到就储存在request域中,如果没有找到则创建再储存。(DefaultActionMapper)
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) {
boolean handled = execute.executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
} else {
//如果执行动作后,该过滤器没有方行,所以说明这个struts过滤器只能放在最后
execute.executeAction(request, response, mapping);//执行动作
}
}
} finally {
prepare.cleanupRequest(request);
}
//创建actioncontext
public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
ActionContext ctx;
Integer counter = 1;
Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
if (oldCounter != null) {
counter = oldCounter + 1;
}
ActionContext oldContext = ActionContext.getContext();//获得原来的actioncontext(如果存在)
if (oldContext != null) {
// 创建一个新的的actiontext,并把原来的context传进去
ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
} else {
//通过工厂模式创建一个valuestack
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
//通过分发器创建一个的map集合(context)并把它方法valuestack的context中去
//所以statck值栈中也有context的索引
stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
ctx = new ActionContext(stack.getContext());
}
request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
//设置ActionContext
ActionContext.setContext(ctx);
return ctx;
}
//执行
Configuration config = configurationManager.getConfiguration();//根据配置文件创建一个代理对象
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, extraContext, true, false);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
// if the ActionMapping says to go straight to a result, do it!
if (mapping.getResult() != null) {
Result result = mapping.getResult();//如果返回结果,则递归调用拦截器后处理过程
result.execute(proxy.getInvocation());
} else {
proxy.execute();//调用actioninvocation调用拦截器
}本文出自 “7317437” 博客,请务必保留此出处http://7327437.blog.51cto.com/7317437/1619509
原文:http://7327437.blog.51cto.com/7317437/1619509