Struts2 StrutsPrepareAndExecuteFilter 源码分析

1、StrutsPrepareAndExecuteFilter 源码分析
自己阅读 Struts2 源码时对 Struts2 StrutsPrepareAndExecuteFilter 过滤器进行了一些注释,有助于自己理解源码的设计理念

2、源代码注释

package org.apache.struts2.dispatcher.ng.filter;

import org.apache.struts2.StrutsStatics;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.ng.ExecuteOperations;
import org.apache.struts2.dispatcher.ng.InitOperations;
import org.apache.struts2.dispatcher.ng.PrepareOperations;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Handles both the preparation and execution phases of the Struts dispatching process.  This filter is better to use
 * when you don't have another filter that needs access to action context information, such as Sitemesh.
 *
 * 该类是配置在 web.xml 中的 struts2 的核心过滤器
 *
 * struts2 请求预处理 and 执行业务逻辑的执行入口类
 *
 */
public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter {

    // struts2 进行 Http 请求预处理的操作集合
    protected PrepareOperations prepare;

    // struts2 进行 Http 请求逻辑处理的操作集合
    protected ExecuteOperations execute;

    //排除在 Struts2 处理之外的 url 模式
    protected List<Pattern> excludedPatterns = null;

    public void init(FilterConfig filterConfig) throws ServletException {

        //初始化操作类
        InitOperations init = new InitOperations();

        //struts2 的核心分发器
        Dispatcher dispatcher = null;
        try {
            FilterHostConfig config = new FilterHostConfig(filterConfig);
            init.initLogging(config);

            //核心分发器的初始化
            dispatcher = init.initDispatcher(config);

            // 初始化静态资源加载器
            init.initStaticContentLoader(config, dispatcher);

            //Http 预处理操作类
            prepare = new PrepareOperations(dispatcher);

            //Http 请求处理的逻辑操作类
            execute = new ExecuteOperations(dispatcher);

            //
            this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

            // 扩展方法
            postInit(dispatcher, filterConfig);
        } finally {
            if (dispatcher != null) {
                dispatcher.cleanUpAfterInit();
            }
            init.cleanup();
        }
    }

    /**
     * Callback for post initialization
     */
    protected void postInit(Dispatcher dispatcher, FilterConfig filterConfig) {
    }

    /**
     *  struts2 的 执行入口,以Filter为切入点
     *
     * @param req
     * @param res
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    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)) {

                //对过滤掉的url进行处理
                chain.doFilter(request, response);
            } else {
                // 设置 encoding、locale
                prepare.setEncodingAndLocale(request, response);

                // 创建ActionContext
                prepare.createActionContext(request, response);

                // todo 把核心分发器 Dispatcher 分配给当前线程
                prepare.assignDispatcherToThread();

                // 利用装饰模式对request进行包装,将其转化为了:StrutsRequestWrapper or MultiPartRequestWrapper
                request = prepare.wrapRequest(request);

                // 根据request请求查找 ActionMapping
                ActionMapping mapping = prepare.findActionMapping(request, response, true);

                // 通过request ----> ActionMapping ----> Dispatcher
                if (mapping == null) {

                    // 没找到ActionMapping 判断是否需要将请求处理为静态资源
                    boolean handled = execute.executeStaticResourceRequest(request, response);
                    if (!handled) {
                        chain.doFilter(request, response);
                    }
                } else {
                    //真正执行Action的地方
                    execute.executeAction(request, response, mapping);
                }
            }
        } finally {
            // 这里面包含了 ActionContext 的销毁过程, ActionContext 横跨了整个XWork控制流执行周期
            prepare.cleanupRequest(request);
        }
    }

    //清理分发器
    public void destroy() {
        prepare.cleanupDispatcher();
    }

}

3、下载源代码
对Struts2 源码感兴趣的读者可以自行去gitHub上下载;
也可以下载我提交到gitHub上的源码,其中包括参考书籍《Struts2架构设计与实现原理》- 陆舟
https://github.com/wangyingjie/structs2Src.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值