struts2
要使用struts2必须在web.xml中配置filter<filter><filter-name>struts2</filter-name><filter-
class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class></filter>
<filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping>
public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter StrutsPrepareAndExecuteFilter是一个过滤器,它会对filtre-mapping中的所有请求进行处理,
protected PrepareOperations prepare; protected ExecuteOperations execute; protected List<Pattern> excludedPatterns = null; public void init(FilterConfig filterConfig) throws ServletException { InitOperations init = new InitOperations(); try { FilterHostConfig config = new FilterHostConfig(filterConfig); init.initLogging(config); Dispatcher dispatcher = init.initDispatcher(config); init.initStaticContentLoader(config, dispatcher); prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher); execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher); this.excludedPatterns = init.buildExcludedPatternsList(dispatcher); postInit(dispatcher, filterConfig); } finally { init.cleanup(); } }
StrutsPrepareAndExecuteFilter在初始化的时候会读取配置文件的信息,在初始化的时候根据FilterConfig的信息来构建InitOperations,PrepareOperations,ExecuteOperations,List<Pattern> excludedPatterns,其中InitOperations是容器初始化操作,例如构建Dispatcher,日志LoggerFactory,静态资源加载器StaticContentLoader,构建Struts2不处理的URL列表也就是List<Pattern> excludedPatterns(这个可以通过struts.action.excludePattern进行设定)等
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try { prepare.setEncodingAndLocale(request, response); prepare.createActionContext(request, response); prepare.assignDispatcherToThread(); if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) { chain.doFilter(request, response); } else { 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是在doFilter的时候进行一些操作,1.prepare.setEncodingAndLocale(request, response); 为request和response进行encoding和Locale,2.prepare.createActionContext(request, response);为当前线程创建ActionContext,ActionContext是
ThreadLocal的,ActionContent其实就是一个线程安全的HashMap,它内部使用一个HashMap来储存相关信息,这个
map的构造是使用dispatcher.createContextMap(request, response, null, servletContext)来形成的,这个
map包括的信息有session,request,response,ServletContext,RequestMap,SessionMap等各种信息,可以通
个这个ActionContent取得各种信息,例如ActionContext.getContext().getSession()来获得当前的Session,
如果要获得request或者response必须用ServletActionContext它是ActionContent的子类,提供更多的方法,如
果是forward那也会新建一个新的ActionContent,这个新的ActionContent直接使用旧的ActionContent的数据来构造
3.prepare.assignDispatcherToThread();把dispatcher绑定到当前线程上,这样就可以通过
Dispatcher.getInstance()来获得当前线程的dispatcher,这样dispatcher就可以被所有请求共享
以上操作完成后就根据excludedPatterns来判断这个请求是否应该交给当前这个filter进行处理,如果不需要就调
用chain.doFilter(request, response);交给其他filter进行处理,如果需要,那么PrepareOperations就执行
4.request = prepare.wrapRequest(request);对request进行包装,包装成StrutsRequestWrapper或者
MultiPartRequestWrapper(请求类型是multipart/form-data的情况)
5 ActionMapping mapping = prepare.findActionMapping(request, response, true);根据request的请求找
到对应的ActionMapping,如果返回的是null,那就当做静态资源进行处理boolean handled = execute.executeStaticResourceRequest(request, response);处理失败就交给其他的filter,如果返回的不是null,那么就调用execute.executeAction(request, response, mapping);处理完成之后 prepare.cleanupRequest(request);会把当前线程的ActionContext和Dispatcher设置为null
ActionMapping的构造:
public class ActionMapping { private String name;//action的名字 private String namespace;//所属package的namespace private String method;//action的方法 private String extension;//请求的url中的额外信息 private Map<String, Object> params;//action名字之前的信息 private Result result;//视图 }
prepare.findActionMapping(request, response, true)根据请求获得ActionMapping ,struts2默认使用
DefaultActionMapper来进行查找