strus2学习笔记―流程

启动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调用拦截器
            }


你可能感兴趣的:(struts,流程)