Board logo

标题: Struts2 内核之我见(4) [打印本页]

作者: look_w    时间: 2018-9-23 12:54     标题: Struts2 内核之我见(4)

对 doFilter() 方法的几点说明 :
下边,我们将讨论 dispatcher 类。
org.apache.struts2.dispatcher.DispatcherDispatcher 做为实际派发器的工具类,委派大部分的处理任务。核心控制器持有一个本类实例,为所有的请求所共享。本部分分析了两个重要方法。
serviceAction():加载 Action 类,调用 Action 类的方法,转向到响应结果。响应结果指代码清单 5 中 <result/> 标签所代表的对象。
cleanup():释放所有绑定到 dispatcher 实例的资源。
serviceAction 方法根据 action Mapping 加载 Action 类,调用对应的 Action 方法,转向相应结果。
首先,本方法根据给定参数,创建 Action context。接着,根据 Action 的名称和命名空间,创建 Action 代理。( 注意这代理模式中的代理角色 ) 然后,调用代理的 execute() 方法,输出相应结果。
如果 Action 或者 result 没有找到,将通过 sendError() 报 404 错误。
清单 7. serviceAction 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public void serviceAction(HttpServletRequest request, HttpServletResponse response,
          ServletContext context,  ActionMapping mapping) throws ServletException {
         Map<String, Object> extraContext = createContextMap
                     (request, response, mapping, context);

        //1 以下代码目的为获取 ValueStack,代理在调用的时候使用的是本值栈的副本
        ValueStack stack = (ValueStack) request.getAttribute
                     (ServletActionContext.STRUTS_VALUESTACK_KEY);
        boolean nullStack = stack == null;
        if (nullStack) {
            ActionContext ctx = ActionContext.getContext();
            if (ctx != null) {
                stack = ctx.getValueStack();
            }
        }
       //2 创建 ValueStack 的副本
        if (stack != null) {
            extraContext.put(ActionContext.VALUE_STACK,
                     valueStackFactory.createValueStack(stack));
        }
        String timerKey = "Handling request from Dispatcher";
        try {
            UtilTimerStack.push(timerKey);
        //3 这个是获取配置文件中 <action/> 配置的字符串,action 对象已经在核心控制器中创建
            String namespace = mapping.getNamespace();
            String name = mapping.getName();
            String method = mapping.getMethod();
            // xwork 的配置信息
            Configuration config = configurationManager.getConfiguration();

            //4 动态创建 ActionProxy
ActionProxy proxy =
config.getContainer().getInstance(ActionProxyFactory.class).
createActionProxy(namespace, name, method, extraContext, true, false);
            
            request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY,
                     proxy.getInvocation().getStack());

            
            //5 调用代理
            if (mapping.getResult() != null) {
                Result result = mapping.getResult();
                result.execute(proxy.getInvocation());
            } else {
                proxy.execute();
            }

            //6 处理结束后,恢复值栈的代理调用前状态
            if (!nullStack) {
                request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
            }
        } catch (ConfigurationException e) {
             //7 如果 action 或者 result 没有找到,调用 sendError 报 404 错误
             if(devMode) {
                 LOG.error("Could not find action or result", e);
             }
             else {
                 LOG.warn("Could not find action or result", e);
             }
            sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
        } catch (Exception e) {
            sendError(request, response, context,
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
              } finally {
            UtilTimerStack.pop(timerKey);
        }
}




几点说明:





欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0