Struts2 中StrutsPrepareAndExecuteFilter的研究
来源:互联网 发布:unity3d path 编辑:程序博客网 时间:2024/06/05 07:19
通过研究StrutsPrepareAndExecuteFilter的逻辑代码来了解下Struts2。注:Struts2 ver2.1.6。
在web项目中添加struts2时,需要在web.xml
添加StrutsPrepareAndExecuteFilter
<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>
可以看出struts2是通过配置\
关于Filter
Filter
有三个方法,
init(FilterConfig)
doFilter(ServletRequest, ServletResponse, FilterChain)
destroy()
Servlet容器(tomcat等)负责调用init(FilterConfig)
创建实例,实际干活的是doFilter(ServletRequest, ServletResponse, FilterChain)
,而销毁实例的时候(比如在IDE里修改了Filter
需要重新编译)会调用destroy()
。
一个Filter
的简单实现如下(WeBFilter
等注解在Servlet 3.0以上才有,3.0以下的需要在web.xml下配置)
@WebFilter(filterName="dataFilter", urlPatterns="/dataServlet", initParams = { @WebInitParam(name="user", value="u"), @WebInitParam(name="password", value="p") })public class DataFilter implements Filter{ public void init(FilterConfig filterConfig) throws ServletException { System.out.println("dataFiler init"); Enumeration<String> enums = filterConfig.getInitParameterNames(); while(enums.hasMoreElements()){ String paramName = enums.nextElement(); String paramValue = filterConfig.getInitParameter(paramName); System.out.println(paramName + "->" + paramValue); } } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("dataFiler service"); chain.doFilter(request, response); } public void destroy() { System.out.println("dataFiler destroy"); } }
关于StrutsPrepareAndExecuteFilter
看回StrutsPrepareAndExecuteFilter
,首先看创建StrutsPrepareAndExecuteFilter实例时调用的方法
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(); } }
- 创建InitOperations和FilterHostConfig。InitOperations主要用于初始化,FilterHostConfig将FilterConfig(由Servlet容器创建)封装,有
getInitParameter(String)
、getServletContext()
和getInitParameterNames()
,前两者是调用FilterConfig的相同方法,而getInitParameterNames()
则是返回类型从Enumeration<String>
转为Iterator<String>
的方法。 - 创建LoggerFactory并设置为项目LoggerFactory。
InitOperations.initLogging
主要从FilterHostConfig.getInitParameter("loggerFactory")
获取类名,然后加载到内存后通过反射创建实例,再通过LoggerFactory.setLoggerFactory(fac)
设置。 - 创建Dispatcher。将FilterConfig的ServletContext和转换为HashMap形式的initparams传递Dispatcher,并通过
Dispatcher.init()
初始化参数添加到ConfigurationManager。Dispatcher.init()
调用了许多私有方法,按序从配置文件(struts.properties,.xml文件,\
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); } }
- 设置request的encoding和response的locale,如果由默认值。
- 创建ActionContext。ActionContext用于处理Servlet,是ThreadLocal类型的。
- 将init()中创建的Dispather设置为当前线程的dispatcher。Dispather也是是ThreadLocal类型的。
- 对于符合Pattern的servlet相关的URL,调用FilterChain处理;否则根据content-type处理,multipart/form-data需要特别对待;创建ActionMapping,代表相应的Action,如果ActionMapping为空则以静态资源流的方式写回浏览器端,或是正常请求则调用FilterChain,如果ActionMapping不为空,则是ActionProxy根据result执行,没有相关的Action则使用Dispatcher#sendError返回404到浏览器端。
- 销毁request,实际上将CLEANUP_RECURSION_COUNTER属性值减1,并且ActionConText和Dispatcher置空。
注意的是只实现HTTP,静态资源只认可/struts/或/static/
public void destroy() { prepare.cleanupDispatcher(); }
其实就是清除Dispatcher,并且再一遍ActionConText置空。
阅读全文
0 0
- Struts2 中StrutsPrepareAndExecuteFilter的研究
- struts2中StrutsPrepareAndExecuteFilter 异常
- struts2的StrutsPrepareAndExecuteFilter
- 深入研究Struts2(二)-StrutsPrepareAndExecuteFilter源码剖析
- 深入研究Struts2(二)-StrutsPrepareAndExecuteFilter源码剖析
- struts2中StrutsPrepareAndExecuteFilter参数配置
- Struts2中StrutsPrepareAndExecuteFilter源码浅析
- Struts2 StrutsPrepareAndExecuteFilter与FilterDispatcher的区别
- struts2 FilterDispatcher 和 StrutsPrepareAndExecuteFilter 的区别
- struts2 FilterDispatcher 和 StrutsPrepareAndExecuteFilter 的区别
- Struts2中的FilterDispatcher和StrutsPrepareAndExecuteFilter的区别
- struts2 FilterDispatcher 和 StrutsPrepareAndExecuteFilter 的区别
- Struts2中的FilterDispatcher和StrutsPrepareAndExecuteFilter的区别
- struts2 FilterDispatcher 和 StrutsPrepareAndExecuteFilter 的区别
- struts2 FilterDispatcher 和 StrutsPrepareAndExecuteFilter 的区别
- Struts2中的FilterDispatcher和StrutsPrepareAndExecuteFilter的区别
- Struts2中的FilterDispatcher和StrutsPrepareAndExecuteFilter的区别
- struts2 FilterDispatcher 和 StrutsPrepareAndExecuteFilter 的区别
- 笔记13 《C++ 大学教程》
- 栈和队列
- android studio 错误:类重复 解决办法
- 代理服务器(Upstream-server)
- 红黑树(RB-tree)比AVL树的优势在哪?
- Struts2 中StrutsPrepareAndExecuteFilter的研究
- python中的编码问题
- hibernate 级联映射
- 8-7
- spring的入门之helloworld
- 第二章:Spark下载与入门
- Linux学习(十一):不可忽略的Linux支持的文件系统
- 大数据学习
- 作为产品经理,这些个性化推荐和热度算法你都掌握了吗?