2022年Struts框架核心代码分析 .pdf
I 代码分析报告Struts2框架核心代码分析专业:?学号:?姓名:?二零一二年十一月名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 30 页 - - - - - - - - - II 目录一、引言 . 1二、 Struts2 的发展过程 . 52.1 Struts1 . 52.2 WebWork . 62.3 Struts 2的诞生 . 62.4 相对 struts1.2,struts2.0的新特性及其实现. 72.5struts2.0 的 MVC 模式与 struts1.0的 MVC 模式区别 . 9三、 Struts 2 框架. 93.1 使用 Struts2.0 实现 MVC . 93.2 Struts 2 配置文件 . 113.3 Struts 2 控制器 . 123.4 Struts 2 标签库 . 12四、 Struts2 源代码分析 . 134.1 下载 struts-2.3.4.1-all-src.zip . 134.2 核心代码分析 . 154.3Struts2请求处理源码过程. 23五、 Struts 2 框架应用举例 . 25六、结论 . 28名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 30 页 - - - - - - - - - 1 Struts2框架核心代码分析一、引言Apache Struts2 是一个为企业级应用打造的优秀的、可扩展的Web 框架。该框架旨在充分精简应用程序的开发周期,从而减少创建、发布、应用所花费的时间。而且对于Struts1 有很多革命性的改进,但它并不是全新的框架,而是在WebWork 框架的基础上发展起来的。 所以也可以说Struts2 是 WebWork 的升级, 吸收了 Struts1 和 WebWork 的优势,稳定性、性能都有了很好的保证。作为一个对java web 学习的初学者、菜鸟,首先让我们先了解下这几个名词:1.MVC 框架MVC (Model View Controller)本来是存在于Desktop 程序中的, M 是指数据模型,V 是指用户界面, C 则是控制器。使用MVC 的目的是将M 和 V 实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据你可以分别用柱状图、饼图来表示。 C 存在的目的则是确保M 和 V 的同步,一旦M 改变, V 应该同步更新。MVC是一个设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 30 页 - - - - - - - - - 2 图 1.1 MVC 模式MVC 的处理过程, 首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。2.框架框架是为了解决一个又一个在Web 开发中所遇到的问题而诞生的。不同的框架,都是为了解决不同的问题,但是对于程序员而言,他们只是jar 包而已。框架的优缺点的评论,也完全取决于其对问题解决程度和解决方式的优雅性的评论。在现在的java web 主流编程中有许多框架,比如Struts、Spring、Hibernate 等。3.设计模式名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 30 页 - - - - - - - - - 3 我是在考软件设计师时学到了设计模式的,当时对设计模式的理解是对在某种环境中反复出现的问题以及解决该问题的方案的描述,是一种比框架要抽象的概念。框架可以用代码表示, 也能直接执行或复用,而对模式而言只有实例才能用代码表示,设计模式是比框架更小的元素, 一个框架中往往含有一个或多个设计模式,框架总是针对某一特定应用领域,但同一模式却可适用于各种应用。在 Struts2 中有一些核心的设计模式,甚至贯穿了整个Struts2 的逻辑主线,成为Struts2内部实现中不可或缺的重要组成部分。在Struts2 中,我们将先后接触到命令(Command)模式、 ThreadLocal 模式、装饰(Decorator)模式、策略(Strategy)模式、构造(Builder )模式、责任链(Chain Of Responsibility )模式、代理(Proxy )模式等等。这些设计模式的反复使用,使得Struts2 的实现本身就充满了最佳实践。4.JSP JSP 技术提供一种简单快速的方法来创建显示动态生成内容的Web 页面,其目的是使得构造基于Web 的应用开发程序更加容易和快捷,而这些程序能够与各种Web 服务器、 应用服务器、游览器和开发工具协同工作。JSP 网页由传统的网页HTML 文件( *.htm 和*.html )中加入java 程序片段( Scriptlet)和 JSP 标记( tag)所构成。 Web 服务器在遇到访问JSP 网页的请求时,首先执行其中的程序片段,然后将执行结果以HTML 格式返回给客户。所以程序操作都在服务器端执行,网络上传送给客户端的仅仅是结果,对客户游览器的要求比较低。由 JSP 推出后,众多大公司都推出了支持JSP 技术的服务器,如IBM 、Oracle 及 Bea公司等,由此JSP迅速成为商业应用的服务器端语言。5.Servlet Servlet 是 JSP 的本质,所有的JSP 页面在执行时都会被服务器端的JSP 引擎转换为Servlet。由于 JSP 引擎调用Java 编译器, 将 Servlet 编译成 .class 文件,并由 JVM 解释执行,然后即可通过服务器端向客户发布JSP网页。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 30 页 - - - - - - - - - 4 一个 Servlet 请求就是Java 编程语言中的一个类,用来扩展服务器的性能,服务器中驻留可以通过 “ 请求 响应 ” 编程模型来访问的应用程序。虽然Servlet 可以响应任何类型的请求,但是通常只用来扩展Web 服务器的应用程序,Java Servlet 技术为这些应用程序定义了一个特定于HTTP 的 Servlet 类。Servlet 通过创建一个框架来扩展服务器的能力,以提供在Web 上的请求和响应服务。当客户端发送请求至服务器时,服务器可以将请求信息发送给Servlet,并由其建立服务器返回给客户端的响应。当启动Web 服务器或者接收到客户端的第一次请求服务时,可以自动装入 Servlet。装入后, Servlet 继续运行,直到其他客户端发出请求。6.Web 服务器简单介绍其中一种应用比较广泛的Tomcat,Tomcat是 Apache 软件基金会(Apache Software Foundation )的 Jakarta 项目中的一个核心项目,由 Apache、Sun 和其他一些公司及个人共同开发而成。 由于有了 Sun 的参与和支持, 最新的 Servlet 和 JSP规范总是能在Tomcat中得到体现。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。Tomcat 是一个轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用, 是开发和调试JSP 程序的首选。 对于一个初学者来说,可以这样认为, 当在一台机器上配置好Apache 服务器, 可利用它响应对HTML 页面的访问请求。实际上 Tomcat 部分是 Apache 服务器的扩展,但它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与 Apache 独立的进程单独运行的。这里的诀窍是,当配置正确时,Apache 为 HTML页面服务,而Tomcat 实际上运行JSP 页面和 Servlet。7.Java Bean JavaBean大部分是用在web 项目里,是一个后台的类,提供给前台的JSP 页面使用,这个类完成某个功能,比方说,往数据库加条记录,中文转码。JavaBean说白了不过是一个Java 类,和普通的 Java 类差不多, 区别有 3 个:1.用 private把不必要的属性隐藏起来,通过属性的getter 和 setter 使类外可以拿到这些属性或者给它们设置值; 2.必须实现序列化接口(java.io.Serializable ),这是为了以后能把这个类的对象保名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 30 页 - - - - - - - - - 5 存在硬盘上; 3.必须有一个public 的无参构造函数,因为使用者可能需要通过反射机制来实例化这个对象。除此之外JavaBean 跟普通Java 类没有区别。这样的一个Java 类(也就是JavaBean), 你可以在JSP页面上使用sun 提供给我们的标签来操作它。如果你写了一个类,这个类没有遵从上面那3 个标准的话, 你在 jsp 页面里用标签来操作这个类,可能会出错的。二、 Struts2 的发展过程接着让我们了解下Struts2的起源和背景。2.1 Struts1 在过去, Struts1 是所有 MVC 框架中不容辩驳的胜利者。其程序运行流程如图2.1所示。图 2.1 Struts 1 的程序运行流程但是对于 Struts 1 框架而言,因为它存在着不少问题:1.与 JSP/Servlet耦合非常紧密,难于测试。2.支持的表现层技术单一,只支持JSP作为表现出技术,不提供其他表现层技术,严重制约了其使用。3.代码严重依赖于Struts 1 API,属于侵入式设计。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 30 页 - - - - - - - - - 6 随着 Web 应用的拙见扩大, 这些缺陷逐渐变成制约Struts 1 发展的的重要因素这也是 Struts 2出现的原因。2.2 WebWork WebWork 来自另外一个优秀的开源组织:opensymphony 。 WebWork 2 建立在 Xwork之上, 处理 HTTP 的请求和响应, 所有的请求都会被前端控制器截获。前端控制器对请求的数据进行包装、 初始化上下文数据、 根据配置文件查找请求URL 对应的 Action 类、执行 Action,并将执行结果转发到相应地展现页面。WebWork2 支持多视图表示,试图部分可以使用JSP、Velocity、FreeMarker 、JasperReport和 XML 等。它采用了更加松耦合的设计,让系统的Action 不再与 Servlet API 耦合。允许系统从 B/S 结构向 C/S 结构转换。而且相对于Struts 1 仅支持 JPS表现层技术的缺陷而言,WebWrok 支持更多的表现层技术。相对于 Struts1 的种种缺点, WebWork 具有如下优点:1.Action 不必与 ServletAPI 耦合,更容易测试。2.Action 不必与 WebWork 耦合,代码重用率高。3.支持更多的表现层技术,有更好的适应性。2.3 Struts 2的诞生在 Struts 2虽然是在 Struts 1的基础上发展起来的, 但实质上是以WebWork 为核心。从某种程度上来讲, Struts2没有继承Struts1, 而是继承了 WebWork 的血统。因为 Struts2是 WebWork 的升级,而不是一个全新的框架,因此稳定性及性能等各方面都有很好的保证。Struts 2为传统 Struts 1注入了 WebWork 的设计理念,它吸收了 Struts1和 WebWork二者的优势,统一了Struts 1 和 WebWork 两个框架。 Struts 2 大量使用拦截器来处理用户请求,从而允许用户的业务逻辑控制器与ServletAPI 分离。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 30 页 - - - - - - - - - 7 2.4 相对 struts1.2 ,struts2.0的新特性及其实现Struts2 与 Struts1 体系的差别非常大,因为前者使用了WebWork 的设计核心, 而不是使用后者的设计核心。Struts2 大量使用拦截器来处理用户请求,从而允许用户的业务逻辑控制器与ServletAPI 分离。Struts2 是一个雅致、可扩展并用来建立企业级Java Web应用程序的框架,不但注重程序的开发过程, 更注重部署和后期维护。 它容易使用, 并且最大可能地保留Struts1.X的相似性。1.Action 类Struts1 要求 Action 类继承一个抽象基类。Struts1 的一个普遍问题是使用抽象类编程而不是接口。Struts2Action 类可以实现一个Action 接口, 也可实现其他接口, 使可选和定制的服务成为可能。 Struts2 提供一个 ActionSupport 基类去实现常用的接口。Action 接口不是必须的,任何有execute标识的 POJO 对象都可以用作Struts2的 Action 对象。2.线程模式Struts1 Action 是单例模式并且必须是线程安全的,因为仅有Action 的一个实例来处理所有的请求。单例策略限制了Struts1 Action 能作的事,并且要在开发时特别小心。Action 资源必须是线程安全的或同步的。Struts2 Action 对象为每一个请求产生一个实例,因此没有线程安全问题。 (实际上,servlet 容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)3.Servlet 依赖Struts1 Action 依赖于 Servlet API,因为当一个 Action 被调用时 HttpServletRequest 和HttpServletResponse 被传递给 execute方法。Struts2 Action 不依赖于容器,允许 Action 脱离容器单独被测试。如果需要, Struts2 Action 仍然可以访问初始的request和 response 。但是,其他的元素减少或者消除了直接访问 HttpServetRequest和 HttpServletResponse的必要性。4.可测性测试 Struts1 Action 的一个主要问题是execute()方法暴露了servlet API (这使得测试要依赖于容器)。为了脱离Web 容器测试 Struts1 的 Action,必须借助于第三方扩展 Struts TestCase 提供了一套Struts1 的模拟对象(来进行测试)。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 30 页 - - - - - - - - - 8 Struts2 Action 可以通过初始化、设置属性、调用方法来测试, “ 依赖注入 ” 支持也使测试更容易。5.捕获输入Struts1 使用 ActionForm 对象捕获输入。所有的 ActionForm 必须继承一个基类。因为其他 JavaBean不能用作 ActionForm ,开发者经常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm 的选择,但是, 开发者可能是在重新描述(创建 )已经存在的 JavaBean(仍然会导致有冗余的javabean)。Struts2 直接使用Action 属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的 rich 对象类型。Action 属性能够通过web页面上的 taglibs访问。 Struts2 也支持 ActionForm 模式。 rich 对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven 特性简化了taglib 对 POJO 输入对象的引用。6.表达式语言Struts1 整合了 JSTL,因此使用 JSTL 表达式语言。 这种表达式语言有基本对象图遍历,但是对集合和索引属性的支持很弱。Struts2 可以使用JSTL,但是也支持一个更强大和灵活的表达式语言Object Graph Notation Language (OGNL) 。7.绑定值到页面(view)Struts1 使用标准JSP机制把对象绑定到页面中来访问。Struts2 使用 ValueStack 技术,使标签库能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack 策略允许通过一系列名称相同但类型不同的属性重用页面(view)。8.类型转换Struts1ActionForm 属性通常都是String 类型。 Struts1 使用 Commons-Beanutils 进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。Struts2 使用 OGNL 进行类型转换。提供基本和常用对象的转换器。9.校验Struts1支持在 ActionForm 的 validate 方法中手动校验, 或者通过 Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 30 页 - - - - - - - - - 9 Struts2 支持通过validate 方法和 XWork 校验框架来进行校验。XWork 校验框架使用为属性类类型定义的校验和内容校验,来支持chain 校验子属性。10.Action 执行的控制Struts1 支持每一个模块有单独的Request Processors (生命周期) ,但是模块中的所有 Action 必须共享相同的生命周期。Struts2 支持通过拦截器堆栈(Interceptor Stacks)为每一个Action 创建不同的生命周期。堆栈能够根据需要和不同的Action 一起使用。2.5struts2.0的 MVC 模式与 struts1.0的 MVC 模式区别struts2 的 mvc 模式:当用户在页面提交用户请求时,该请求需要提交给struts2的控制器处理。 struts2 的控制器根据处理结果,决定将哪个页面呈现给客户端。与 struts1 最大的不同是: struts2的控制器。 struts2的控制器不再像struts1 的控制器 ,需要继承一个Action 父类 ,甚至可以无需实现任何接口,struts2的 Action 就是一个普通的POJO(简单实体类) 。实际上, Struts2的 Action 就是一个包含execute方法的普通Java类该类里包含的多个属性用于封装用户的请求参数。三、 Struts 2 框架3.1 使用 Struts2.0实现 MVC 一个请求在 Struts 2框架被处理大致分为一下几个步骤,如图3.1所示:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 30 页 - - - - - - - - - 10 图3.1 Struts 2工作机制(1)客户端初始化一个指向Servlet 容器(例如Tomcat)的请求;( 2) 这 个 请 求 经 过 一 系 列 的 过 滤 器 ( Filter ) ( 这 些 过 滤 器 中 有 一 个 叫 做ActionContextCleanUp 的可选过滤器, 这个过滤器对于Struts2 和其它框架的集成很有帮助,例如: SiteMesh Plugin);(3)接着 FilterDispatcher 被调用, FilterDispatcher 询问 ActionMapper 来决定这个请求是否需要调用某个Action;名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 30 页 - - - - - - - - - 11 (4)如果 ActionMapper 决定需要调用某个Action,FilterDispatcher 把请求的处理交给ActionProxy ;(5)ActionProxy通过 Configuration Manager 询问框架的配置文件,找到需要调用的Action 类;(6)ActionProxy 创建一个 ActionInvocation 的实例;(7)ActionInvocation 实例使用命名模式来调用,在调用Action 的过程前后,涉及到相关拦截器( Intercepter)的调用;(8)一旦 Action 执行完毕, ActionInvocation 负责根据struts.xml 中的配置找到对应的返回 Result。返回 Result通常是(但不总是,也可能是另外的一个Action 链)一个需要被表示的 JSP或者 FreeMarker 的模版。( 9) 如 果 要 在 返 回Result 之 前 做 些 什 么 , 可 以 实 现 PreResultListener 接 口 ,PreResultListener 可以再 Interceptor 中实现,也可以在Action 中实现。(10)根据 Result对象信息,生成用户响应信息response ,在生成响应过程中可以使用Struts2 框架中继承的标签,在这个过程中需要涉及到ActionMapper 。从上述工作机制上可以看出Struts2 的 MVC 模式分离了model 和 view 层,其中Model (数据模型) 用 Java程序 (业务类)来实现,View(表示层)用 JSP 来实现,Controller(控制层) 用 FilterDispatcher 和业务控制器Action 来实现, 这样的模式分离使代码更加清晰易读。3.2 Struts 2配置文件Struts2配置文件是用户请求(View) 和业务逻辑模块(Model)Action 之间联系的桥梁。开发者可以通过修改Struts2的配置文件来快速适应业务需求,它是整个 Struts2的精髓之一。当然,熟悉 Struts1和WebWork 的框架的人对配置文件一定不会陌生,同Struts1和WebWork 框 架一 样 ,Struts2框 架配 置文 件也分 为 XML 文件 和属 性资源 文件 两种 。struts.xml文件中包含了 Action 的定义以及 Action的返回值对应的视图资源、命名空间等名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 30 页 - - - - - - - - - 12 信息。此外 ,用户也可以定义自己的XML 文件 ,然后通过 include指令将其包含到struts.xml文件中。 另一类配置文件是属性资源文件。资源文件中一般采用固定的Key -Value形式,用于定义 Struts2全局或者局部的资源数据,例如定义国际化、开发模式等信息。3.3 Struts 2控制器Struts2 的控制器组建是Struts2 框架的核心,事实上所有 MVC 框架都是以控制器组件为核心的。正如前面提到的,Struts2 的控制器由两个部分组成:FilterDispatcher 和业务控制器 Action。前者由框架提供,负责拦截所有的用户请求,其过程如图3.2 所示图 3.2 过滤器处理请求过程对于业务控制器Action,Struts2框架为用户提供了一个名为Action的接口 ,在接口中定义了 SUCCESS、ERROR 、INPUT 、LOGIN 、NONE 五个静态的字符串和一个execute方法,用户在编写自己的Action时只要实现该接口并重写其中的execute方法,将所要实现的业务逻辑在该方法中处理就行了,当调用此 Action 时,Struts2框架会自调用 execute方法来完成所需的业务逻辑处理。实际上,在Struts2中起作用的业务逻辑并不是用户自定义的 Action,而是系统生成的ActionProxy ,只不过 ActionProxy 以用户定义的 Action为目标。3.4 Struts 2标签库Struts 2 的标签库也是Struts 2的重要组成部分, Struts 2的标签库提供了非常丰富的功能, 这些标签不仅提供了表现层数据处理,而且还提供了基本的流程控制功能,还提供了国际化、 Ajax 支持等功能。 使用标签,开发者可以最大限度地减少页面代码的书写。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 30 页 - - - - - - - - - 13 四、 Struts2 源代码分析4.1 下载 struts-2.3.4.1-all-src.zip Struts 是开源框架, 可以从官方网站http:/struts.apache.org/下载 Struts2 源代码文件,最新版本为struts-2.3.4.1-all-src.zip。解压出的文件夹中里面的目录和文件非常多,可以在 srccoresrcmainjavaorgapachestruts 目录下查看Struts2 的源文件。图 4.1 Struts2 源代码目录Struts2 框架的正常运行, 除了占核心地位的xwork 的支持以外, Struts2 本身也提供了许多类,这些类被分门别类组织到不同的包中。从源代码中发现, 基本上每一个Struts2类都访问了WebWork 提供的功能,从而也可以看出Struts2 与 WebWork 千丝万缕的联系。但无论如何,Struts2 的核心功能比如将请求委托给哪个Action 处理都是由xwork完成的, Struts2 只是在 WebWork 的基础上做了适当的简化、加强和封装,并少量保留Struts1.x 中的习惯。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 30 页 - - - - - - - - - 14 以下是对各包的简要说明:包名说明components 该包封装视图组件,Struts2 在视图组件上有了很大加强,不仅增加了组件的属性个数,更新增了几个非常有用的组件,如updownselect、doubleselect、datetimepicker、token、tree 等。config 该包定义与配置相关的接口和类。实际上,工程中的xml 和 properties 文件的读取和解析都是由WebWork 完成的, Struts 只做了少量的工作。dispatcher Struts2 的核心包,最重要的类都放在该包中。impl 该包只定义了3个类,他们是 StrutsActionProxy、 StrutsActionProxyFactory 、StrutsObjectFactory,这三个类都是对xwork 的扩展。interceptor 定义内置的截拦器。util 实用包。validators 只定义了一个类:DWRValidator 。views 提供 freemarker、jsp、velocity 等不同类型的页面呈现。下表是对一些重要类的说明:类名说明Dispatcher该类有两个作用:1、初始化 2、调用指定的Action的 execute()方法。FilterDispatcher该类有四个作用:1、执行 Action2、清理ActionContext ,避免内存泄漏3、处理静态内容(Serving static content)4、为请求启动xworks 的截拦器链。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 30 页 - - - - - - - - - 15 struts-2.3.4.1srcxwork-coresrcmaActionProxyAction 的代理接口。ActionProxyFactory生产 ActionProxy 的工厂。ActionInvocation负责调用Action 和截拦器。XmlConfigurationProvider负责 Struts2 的配置文件的解析。dispatcher dispatcherActionMapperActionMapper 其实是 HttpServletRequest 和 Action 调用请求的一个映射,它屏蔽了Action 对于Request 等 java Servlet 类的依赖。 Struts2 中它的默认实现类是DefaultActionMapper ,ActionMapper 很大的用处可以根据自己的需要来设计url 格式,它自己也有Restful 的实现。4.2 核心代码分析良好的框架可以运用语言的特性以及设计模式来实现解耦,struts2 非常好用的两个功能拦截器、扩展view 的显示方式,可以在下述代码找到答案。1) StrutsPrepareAndExecuteFilter struts2 以后 web.xml 的配置已经由配置servlet 变成配置 filter。public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 30 页 - - - - - - - - - 16 HttpServletRequest request = (HttpServletRequest) req; / 请求 HttpServletResponse response = (HttpServletResponse) res; / 响应 try prepare.setEncodingAndLocale(request, response); /设置编码和语言 prepare.createActionContext(request, response); /创建当前线程的ActionContext prepare.assignDispatcherToThread(); /将 dispatcher赋给当前线程 if ( excludedPatterns != null & prepare.isUrlExcluded(request, excludedPatterns) chain.doFilter(request, response); /如果该 URL 被 exclude 掉,继续 chaining else request = prepare.wrapRequest(request); / 包装 request 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); / hit! 将 请 求 交 给dispatcher , 触 发 其serviceAction方 法 (dispatcher.serviceAction(request, response, servletContext, mapping);) finally prepare.cleanupRequest(request); 2) Dispatcher 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页,共 30 页 - - - - - - - - - 17 struts 中的核心类,构造actionproxy 以及 actioninvocation,加载 action 类并调用其方法 public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException Map extraContext = createContextMap(request, response, mapping, context); 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(); if (stack != null) /将值栈 put 进 extraContext extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack); String timerKey = Handling request from Dispatcher; try UtilTimerStack.push(timerKey); String namespace = m