structs2-StrutsPrepareAndExecuteFilter类的理解

使用structs需要配置文件web.xml

  
    struts2  
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter  
  
  
    struts2  
    /*  

Class StrutsPrepareAndExecuteFilter

  • java.lang.Object
    • org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
  • All Implemented Interfaces:
    javax.servlet.Filter,  StrutsStatics
可以看出structs2是利用的过滤器机制来实现自身。
StrutsPrepareFilter类的主要工作有俩点:
一是为struts2执行做一些相关的准备。如加载相关的配置信息。
二是为struts2的request请求处理相关的信息。如设置编码格式和找到对应的action映射类


feild

protected PrepareOperations prepare;  //包含一个请求在执行前的准备操作
protected ExecuteOperations execute;  //包含过滤器的执行操作
protected List excludedPatterns = null; //指定不经过struts2框架处理的URL规则

methods

protected ExecuteOperations	createExecuteOperations(Dispatcher dispatcher)
   //创建一个用于初始化dispathcer的新的ExecuteOperations实例
protected InitOperations	createInitOperations()
   //创建一个用于初始化dispathcer的新的InitOperations实例
protected PrepareOperations	createPrepareOperations(Dispatcher dispatcher)
   //创建一个用于初始化dispathcer的新的PrepareOperations实例
void	destroy() 
void	doFilter(javax.servlet.ServletRequest req, javax.servlet.ServletResponse res, javax.servlet.FilterChain chain) 
void	init(javax.servlet.FilterConfig filterConfig) 
protected void	postInit(Dispatcher dispatcher, javax.servlet.FilterConfig filterConfig)
   //一个空的方法,用于方法回调初始化

两个主要方法

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        try {
            String uri = RequestUtils.getUri(request);
            if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
                LOG.trace("Request {} is excluded from handling by Struts, passing request to other filters", uri);
                chain.doFilter(request, response);
            } else {
                LOG.trace("Checking if {} is a static resource", uri);
                boolean handled = execute.executeStaticResourceRequest(request, response);
                if (!handled) {
                    LOG.trace("Assuming uri {} as a normal action", uri);
             /**************************************************************************************/
                    prepare.setEncodingAndLocale(request, response);
                    prepare.createActionContext(request, response);
					/*为当前线程创建ActionContext,ActionContext是ThreadLocal的,ActionContext其实就是一个线程安全的HashMap,它内部使用一个HashMap
					来储存相关信息这个map包括的信息有session,request,response,ServletContext,RequestMap,SessionMap等各种信息,可以通
					个这个ActionContext取得各种信息*/
                    prepare.assignDispatcherToThread();//部署dispatcher到dispatcher线程本地
                    request = prepare.wrapRequest(request);//包装request
                    ActionMapping mapping = prepare.findActionMapping(request, response, true);//得到ActionMapping
					//(ActionMapping的主要功能就是管理Action的信息和管理Action执行完成以后的ActionForward的信息。)
            /***************************************************************************************/
                    if (mapping == null) {
                        LOG.trace("Cannot find mapping for {}, passing to other filters", uri);
                        chain.doFilter(request, response);
                    } else {
                        LOG.trace("Found mapping {} for {}", mapping, uri);
                        execute.executeAction(request, response, mapping);//执行对应的action。
                    }
                }
            }
        } finally {
            prepare.cleanupRequest(request);//一次请求完毕,清空此请求的缓存
        }
    }

由此见在一个使用Action的request请求传入容器时,会经过StrutsPrepareAndExecuteFilter为其配置ActionContext,包装request,最后找到Action实现类执行。

public void init(FilterConfig filterConfig) throws ServletException {
        InitOperations init = createInitOperations();
        Dispatcher dispatcher = null;
        try {
		//封装filterConfig,其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中
            FilterHostConfig config = new FilterHostConfig(filterConfig);
			// 初始化struts内部日志
            init.initLogging(config);
			//创建dispatcher ,并初始化,dispatcher类的作用还得详细理解
            dispatcher = init.initDispatcher(config);
            init.initStaticContentLoader(config, dispatcher);
			//初始化类属性:prepare 、execute
            prepare = createPrepareOperations(dispatcher);
            execute = createExecuteOperations(dispatcher);
            this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
			//回调空的postInit方法
            postInit(dispatcher, filterConfig);
        } finally {
            if (dispatcher != null) {
                dispatcher.cleanUpAfterInit();
            }
            init.cleanup();
        }
    }


创建Dispatcher,会读取 filterConfig 中的配置信息,将配置信息解析出来,封装成为一个Map,然后根绝servlet上下文和参数Map构造Dispatcher :
Dispatcher初始化,加载struts2的相关配置文件,将按照顺序逐一加载:default.properties,struts-default.xml,struts-plugin.xml,struts.xml。。。。


ilterDispatcher是struts2.0.x到2.1.2版本的核心过滤器.!
StrutsPrepareAndExecuteFilter是自2.1.3开始就替代了FilterDispatcher的.!
这样的改革当然是有好处的.!
为什么这么说.? 应该知道如果我们自己定义过滤器的话, 是要放在strtus2的过滤器之前的, 如果放在struts2过滤器之后,你自己的过滤器对action的过滤作用就废了,不会有效!除非你是访问jsp/html!
那我现在有需求, 我必须使用Action的环境,而又想在执行action之前拿filter做一些事, 用FilterDispatcher是做不到的.!
那么StrutsPrepareAndExecuteFilter可以把他拆分成StrutsPrepareFilter和StrutsExecuteFilter,可以在这两个过滤器之间加上我们自己的过滤器.

你可能感兴趣的:(ssh框架学习)