11.struts2的基本原理(struts2笔记)

这里我们只是讲一下最基本的原理,也就是当页面请求提交过来之后struts2是怎样处理的。
在网上找了一张图,地址是:

http://blog.csdn.net/wuwenxiang91322/article/details/11070513

11.struts2的基本原理(struts2笔记)_第1张图片
struts2原理图.jpg

其中控制器就是 StrutsPrepareAndExecuteFilter或FilterDispatcher。在Struts2.1以前调用 FilterDispatcher,Struts2.1以后调用 StrutsPrepareAndExecuteFilter,控制器通过 ActionMapper得到 action的相关信息,通过 ActionProxy去读取相关配置文件,主要过程是在 ActionInvocation(即DefaultActionInvocation)和实际 action之间。我们就从控制器开始。

首先我们在org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter这个类的doFilter方法开头设置一个断点,使用debug进行跟踪。在此方法中我们可以看到这样一段:

 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);
                }

说明:这里表示如果mapping为空表示没有找到相应的action,否则表示找到了相应的action,找到之后执行

execute.executeAction(request, response, mapping);

方法,我们跟进去,进去之后会发现执行的是方法:

dispatcher.serviceAction(request, response, mapping);

这个dispatcher就是org.apache.struts2.dispatcher.Dispatcher类,即执行Dispatcher类的serviceAction方法,继续跟进去。这个方法为:

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

        Map extraContext = createContextMap(request, response, mapping);

        ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
      ......
        try {
            UtilTimerStack.push(timerKey);
            String namespace = mapping.getNamespace();
            String name = mapping.getName();
            String method = mapping.getMethod();

            ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
                    namespace, name, method, extraContext, true, false);

            request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

            if (mapping.getResult() != null) {
                Result result = mapping.getResult();
                result.execute(proxy.getInvocation());
            } else {
                proxy.execute();
            }
         ......
    }

说明:

  • 1.这个方法中我们首先看这两行
ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

可以看到struts2将值栈存到了request域中,我们以后要想取得值栈中的内容可以使用上面的常量。

  • 2.同时可以看到产生了一个ActionProxy对象,这个对象会通过ConfigurationManager去读取配置文件的相关信息,之后就会执行其execute()方法。跟踪此方法会发现此方法最后
return invocation.invoke();

也就是执行com.opensymphony.xwork2.DefaultActionInvocation对象的invoke方法,而此类中我们可以看到包含了我们自己的action和一系列的拦截器(interceptor)。跟踪此方法:

if (interceptors.hasNext()) {
                final InterceptorMapping interceptor = interceptors.next();
                String interceptorMsg = "interceptor: " + interceptor.getName();
                UtilTimerStack.push(interceptorMsg);
                try {
                                resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
                            }
                finally {
                    UtilTimerStack.pop(interceptorMsg);
                }
            } else {
                resultCode = invokeActionOnly();
            }

说明:代码中这样一段可以看到首先执行各类拦截器,当拦截器执行完之后执行invokeAction()这个方法。
首先我们看

resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);

这里调用的是拦截器的intercept方法,在此方法中我们可以看到

result = invocation.invoke();

也就是说继续调用DefaultActionInvocationinvoke方法,这样就会调用下一个拦截器,当将所有拦截器都调用一遍之后,才会执行DefaultActionInvocationinvokeActionOnly();方法,我们跟进去会发现执行的是

return invokeAction(getAction(), proxy.getConfig());

invokeAction方法中:

String methodName = proxy.getMethod();

此时拿到的方法就是我们的action中的execute方法,然后就执行此方法,之后就返回去,经过一些列的拦截器之后返回到
com.opensymphony.xwork2.DefaultActionInvocation然后返回到org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter类,最后在页面中响应。

最后:根据原理图和debug调试基本上可以对struts的原理有个比较大概的了解了。

你可能感兴趣的:(11.struts2的基本原理(struts2笔记))