`
阅读更多
第一个环节是FilterDispatcher,过滤、包装请求,调用dispatcher的serviceAction方法。主要代码如下:

 1UtilTimerStack.push(timerKey);
 2            request = prepareDispatcherAndWrapRequest(request, response);
 3            ActionMapping mapping;
 4            try {
 5                mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());
 6            }
 catch (Exception ex) {
 7                LOG.error("error getting ActionMapping", ex);
 8                dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
 9                return;
10            }

11
12            if (mapping == null{
13                // there is no action in this request, should we look for a static resource?
14                String resourcePath = RequestUtils.getServletPath(request);
15
16                if ("".equals(resourcePath) && null != request.getPathInfo()) {
17                    resourcePath = request.getPathInfo();
18                }

19
20                if (serveStatic && resourcePath.startsWith("/struts")) {
21                    String name = resourcePath.substring("/struts".length());
22                    findStaticResource(name, request, response);
23                }
 else {
24                    // this is a normal request, let it pass through
25                    chain.doFilter(request, response);
26                }

27                // The framework did its job here
28                return;
29            }

30
31            dispatcher.serviceAction(request, response, servletContext, mapping);

可以看到这里面调用actionMapper找到了当前请求对应的actionMapping。然后就是dispatcher.serviceAction这个方法了。可以想象肯定是找到对应的Action类,执行相应的action方法。Dispatcher类的serviceAction方法主要代码如下:

 1UtilTimerStack.push(timerKey);
 2            String namespace = mapping.getNamespace();
 3            String name = mapping.getName();
 4            String method = mapping.getMethod();
 5
 6            Configuration config = configurationManager.getConfiguration();
 7            ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
 8                    namespace, name, extraContext, truefalse);
 9            proxy.setMethod(method);
10            request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
11
12            // if the ActionMapping says to go straight to a result, do it!
13            if (mapping.getResult() != null{
14                Result result = mapping.getResult();
15                result.execute(proxy.getInvocation());
16            }
 else {
17                proxy.execute();
18            }

19
20            // If there was a previous value stack then set it back onto the request
21            if (stack != null{
22                request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
23            }

可以看到,其中从configurationManager中找到config,在利用config,通过ActionProxyFactory创建了合适的ActionProxy对象。后面就是判断如果当前的mapping存在result,那么直接返回result的执行结果,否则执行proxy.execute。前者的含义我猜是处理某些不需要Action的请求的时候用到的。具体要调用最后的Action中的什么方法也是在这个时候确定的(proxy.setMethod(....))。

上面的代码中,实际上是使用StrutsActionProxyFactory类的createActionProxy方法来创建ActionProxy的。这个方法如下:

1 ActionProxy proxy = new StrutsActionProxy(namespace, actionName, extraContext, executeResult, cleanupContext);
2        container.inject(proxy);
3        proxy.prepare();
4        return proxy;

可以看到创建proxy之后,调用了proxy的prepare方法,于是看DefaultActionProxy类的prepare方法中有这样的代码:

1invocation = new DefaultActionInvocation(objectFactory, unknownHandler, this, extraContext, true, actionEventListener);

实际上是创建了这个proxy中的invocation对象,这个对象很重要,后面是顺着这个对象的invoke方法去执行我们写的Action中的具体方法的。

回头再去看上面第二段代码中,创建proxy之后,调用了proxy的execute方法,这个里面写得很简单:

 1    public String execute() throws Exception {
 2        ActionContext previous = ActionContext.getContext();
 3        ActionContext.setContext(invocation.getInvocationContext());
 4        try {
 5            return invocation.invoke();
 6        }
 finally {
 7            if (cleanupContext)
 8                ActionContext.setContext(previous);
 9        }

10    }

就是执行了invocation的invoke方法。而这个invocation是哪里来的,我们也已经很清楚了。这个invocation类实际上是DefaultActionInvocation类的一个实例。其invoke方法如下:

 1if (executed) {
 2                throw new IllegalStateException("Action has already executed");
 3            }

 4
 5            if (interceptors.hasNext()) {
 6                final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
 7                UtilTimerStack.profile("interceptor: "+interceptor.getName(), 
 8                        new UtilTimerStack.ProfilingBlock<String>() {
 9                            public String doProfiling() throws Exception {
10                                resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
11                                return null;
12                            }

13                }
);
14            }
 else {
15                resultCode = invokeActionOnly();
16            }

17
18            // this is needed because the result will be executed, then control will return to the Interceptor, which will
19            // return above and flow through again
20            if (!executed) {
21                if (preResultListeners != null{
22                    for (Iterator iterator = preResultListeners.iterator();
23                        iterator.hasNext();) {
24                        PreResultListener listener = (PreResultListener) iterator.next();
25                        
26                        String _profileKey="preResultListener: ";
27                        try {
28                            UtilTimerStack.push(_profileKey);
29                            listener.beforeResult(this, resultCode);
30                        }

31                        finally {
32                            UtilTimerStack.pop(_profileKey);
33                        }

34                    }

35                }

36
37                // now execute the result, if we're supposed to
38                if (proxy.getExecuteResult()) <
分享到:
评论

相关推荐

    中兴struts2 时序图

    在《时序图及简要说明.doc》文档中,可能会包含更详细的解释,比如各个组件的具体交互细节、特定场景下的流程变化、异常处理等。这份文档将帮助开发者深入理解Struts2的工作原理,从而更好地应用和优化框架,提高...

    struts-config.xml

    短文本描述,用于简要介绍其父元素的作用。 3. **`&lt;description&gt;`**: 完整的文本描述,提供父元素的详细解释。 4. **`&lt;set-property&gt;`**: 设置JavaBean的属性值,常用于配置数据源参数、ActionMapping扩展...

    刚写的Struts1客户管理系统

    Struts1中的Action类是处理用户请求的中心组件,它实现了业务逻辑并决定后续的处理流程。ActionMapping则定义了Action与URL之间的映射关系,使得用户可以通过不同的URL触发不同的Action。 5. **Tiles框架集成**: ...

    struts2的加载

    在深入探讨Struts2的加载过程前,我们首先简要回顾一下Struts2框架的基本概念。Struts2是Apache组织下的一个开源Web应用框架,它继承了Struts1的优良特性,并在此基础上进行了大量改进,引入了拦截器、类型转换、...

    struts2+hibernate+spring整合

    此外,Struts2还提供了拦截器(Interceptor)机制,允许开发者在请求处理前后插入自定义逻辑。 2. Hibernate:这是一个对象关系映射(ORM)框架,它简化了数据库操作。Hibernate允许开发者使用Java对象来操作数据库...

    Struts+Spring+Hibernate 整合教程.pdf

    - 描述:可以通过覆盖Struts的RequestProcessor来定制处理流程,例如添加额外的拦截器。 - 作用:提高了Struts框架的灵活性,使得开发者可以更好地控制请求的处理流程。 - **窍门3:将动作管理委托给Spring** - ...

    Struts In Action中文版

    这部分内容探讨了Struts框架中请求处理的具体流程。 ##### 2.5.1 总图 Struts框架的控制流主要由ActionServlet启动,它接收HTTP请求,并根据配置文件(struts-config.xml)中的规则决定接下来的动作。 ##### ...

    struts2整合JFreeChart

    此外,描述中提到的"简要的文档说明和代码"可能包括了具体步骤的指导,如如何配置Struts2的拦截器、Action类如何编写、以及JSP页面如何显示图表等。开发者可以参考这些文档来快速理解和实现整合过程。 总的来说,...

    Struts in Action 中文修正版.pdf

    - 在这一节中,作者对Struts框架的历史背景、开源意义以及名称由来进行了解释,并简要介绍了本书的主要内容。 #### 深入Struts架构 ##### 2.1 随便谈谈 - 这部分作为过渡章节,引导读者逐步进入Struts框架的核心...

    公司开发平台说明文档-Struts2 WEB层架构及Java开发规范.doc

    Struts2框架的核心是`Action`类,它是处理用户请求的主要组件。Struts2使用拦截器机制来增强Action的功能,并利用配置文件(如struts.xml)来定义Action与用户界面之间的映射关系。以下是Struts2架构的主要组成部分...

    Structs2核心过滤器

    - **`&lt;filter-class&gt;`**:指定过滤器的具体实现类,这里是`org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter`,这个类负责处理所有进入Struts2框架的HTTP请求。 接下来是`&lt;filter-mapping&gt;`...

    strust2配置

    在深入探讨Struts2配置的关键知识点之前,我们首先简要回顾一下Struts2框架的基本概念。Struts2是Apache软件基金会开发的一个开源Web应用框架,它遵循MVC(Model-View-Controller)设计模式,旨在简化Java Web应用...

    黑客Structs2漏洞利用工具超好用

    在描述中提到的"黑客Structs2漏洞利用工具超好用",这通常指的是开发者或安全研究人员使用的工具,用于检测、模拟或演示Struts2漏洞的利用过程。这些工具可以帮助他们了解漏洞的工作原理,评估其风险,并为防御策略...

    基于java的博客网站设计与开发(毕业论文)

    论文中简要描述了用户请求如何通过Struts框架被分发到相应的业务逻辑处理,然后由业务逻辑层调用数据访问层,完成数据处理后返回结果,最后由视图层将数据渲染成用户可见的网页。 五、问题与解决方案 在开发过程中...

    基于java的博客网站设计与开发毕业论文(含源文件)(20210806171123).pdf

    - 文档可能介绍了页面请求在MVC架构中的流程,包括用户请求如何被控制器接收、业务逻辑如何被处理以及结果如何返回给用户。 - 页面技术方面,可能提到了HTML、CSS、JavaScript等前端技术的使用,以及Ajax技术如何...

    Java客户关系管理系统

    1. Struts2:作为MVC(Model-View-Controller)框架的一部分,Struts2负责处理用户请求,并将这些请求映射到相应的业务逻辑。它提供了灵活的配置和拦截器机制,使得开发者能够更好地控制应用程序的行为。 2. Spring...

    j2ee核心技术笔记

    模型负责数据的存储和检索,视图负责数据的展示,控制器则处理用户请求和控制流程。在分页场景中,控制器可以根据用户的请求参数(如当前页码)调用模型层的分页方法,获取相应页面的数据,然后将其传递给视图进行...

Global site tag (gtag.js) - Google Analytics