struts2源码学习笔记(四)——初探执行action流程

这篇文章我们主要关注的就是executeAction这个方法,对应源码中的位置如下:

我们继续往深了挖代码:

发现还是由dispatcher来处理,继续挖

    public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
            throws ServletException {

        Map<String, Object> extraContext = createContextMap(request, response, mapping);
        
        // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
        ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
        boolean nullStack = stack == null;
        if (nullStack) {
            ActionContext ctx = ActionContext.getContext();
            if (ctx != null) {
                // 如果没有值栈,就从Actioncontext对象中获取
             stack = ctx.getValueStack();
            }
        }
        if (stack != null) {
                // 如果现在已经存在了,就新建一个值栈,并将旧值栈存入到新值栈中
             extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
        }

        String timerKey = "Handling request from Dispatcher";
        try {
            UtilTimerStack.push(timerKey);
                // 获取命名空间,相当于struts.xml中的package
             String namespace = mapping.getNamespace();
                // 获取request请求中的action名称
             String name = mapping.getName();
                // 获取要执行的方法名称
             String method = mapping.getMethod();
                // 获取actionProxy对象
            ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
                    namespace, name, method, extraContext, true, false);
                // 将值栈存入到request域中
            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 {
                // 这里执行action
                 proxy.execute();
            }

            // If there was a previous value stack then set it back onto the request
            if (!nullStack) {
                // 更新request域中的值栈
                 request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
            }
        } catch (ConfigurationException e) {
            logConfigurationException(request, e);
            sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
        } catch (Exception e) {
            if (handleException || devMode) {
                sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
            } else {
                throw new ServletException(e);
            }
        } finally {
            UtilTimerStack.pop(timerKey);
        }
    }

分析以上代码可以发现

1.不管怎么都会更新requst域中的值栈

2.ActionProxy类的proxy对象很重要,但是由于这部分比较复杂,我打算留到下次再来分析

3.在执行action请求前会判断是否直接返回结果

猜你喜欢

转载自blog.csdn.net/qq_41907991/article/details/80776445