4.配置Struts 组件
4.配置Struts 组件
本章内容
Web应用部署描述符
Struts配置文件
应用资源文件
Ant的构建文件
Change alone is unchanging. —Heraclitus (c 535–c 475 B.C.)
4.1. 三个 XML文件和一个属性文件
除了Java 类和JSP 页面之外,开发人员必须创建或者修改几个配置文件以便能够使Struts 应用能运转起来,这些文件包括:
web.xml. 这是Java Servlet 要求的web 应用部署描述符。Servlet/JSP 容器使用这个文件来载入和配置你的应用。
struts-config.xml. Struts 框架的部署描述符。它用来载入和配置Struts 框架使用的各种组件。
Build.xml. Jakarta Ant 构建工具使用它来编译和部署你的应用。使用Ant 不是必需的,但它在Struts 开发人员中很流行。
Application.properties. 该文件为你的Struts 应用提供资源。像build.xml 文件一样,它不是严格要求的,但是大多数Struts 应用都要用到。
尽管处理这些文件看起来也许不象是在进行“Java 开发”, 但是正确的使用它们却是使你的web 应用能拿得出手的基本要求。在这一章,我们会仔细讨论这些文件的工作原理,以及它们能对你的应用的开发和部署起什么作用。
4.1.1. 家族的其他人员
除了每个Struts 应用都需要的配置文件外,还有其它一些Struts 应用也可能要用的东西。如果使用可选的组件,可能还需要另外的XML 配置文件,比如Tiles 框架和Struts Validator 。如果你想要把你的应用分成多个模块,每个模块也要有其自己的Struts 配置和资源文件。
在本章,我们将首先关注核心配置文件,然后来配置Struts 1.1 中的标准配置项。
4.2. Web应用部署描述符
框架的核心是ActionServlet,Struts 把它当作是一个控制器。虽然它也可以被子类化,但大多数开发人员都将它看成是一个黑盒。他们总是在web 应用部署描述符 (web.xml) 中配置它,然后让它自己工作。
ActionServlet 可以接受多个初始化参数。大多数都有合理的缺省值,不需要重新设定。但有一些却必须设置,以便使你的应用能正常工作。
在这一节,我们将考察一个典型的Struts web 部署描述符,并且详细讨论ActionServlet 的初始化参数。
4.2.1. Web.xml 文件
Web 应用部署描述符的目的和格式在Sun Servlet 规范[Sun, JST]中定义。基本上,它告诉servlet 容器如何配置servlet 和应用需要的其它高层次对象。
Struts 框架有两个组件需要从应用部署描述符中配置:ActionServlet 和标签库(可选)。虽然大多数Struts 应用的确需要使用标签库,但它也不是严格要求的。使用XSLT 或者Velocity 的应用根本不需要配置标签库。
清单4.1 是我们的logon 应用的web.xml 文件(见第3 章)。
清单 4.1 Logon 应用的Web.XML
代码中编号的地方对应下面的注释。
①标识为web 应用部署描述符——前两行将文件标识为一个web 应用部署描述符。
②配置 ActionServlet— 这一段告诉容器装入action 名称下的ActionServlet 。有四个参数传递给ActionServlet: 即application,config, debug, 和detail 。(ActionServlet 也可以接受其它参数;我们将再下一节涉及)。这一段的最后一个设定,,给容器一个action servlet 的权重。如果设置为2,则允许其它 servlet 在需要时首先装入。这将在你子类化了ActionServlet 之时显得很重要,以便你可以使用其它servlet 先期装入的资源。对一个应用来说, 仅可以装入一个ActionServlet 或者 ActionServlet 的子类。ActionServlet 设计为可以和应用中的其它组件共享资源。装入多个ActionServlet 会造成冲突;因为一个 ActionServlet 可能会改写另一个ActionServlet 提交的资源。Struts 1.1 支持模块化应用,但仍然只允许装入一个ActionServlet 。
③标识Struts 请求—这一段告诉容器将匹配*.do 格式的文件请求转发到action servlet 。这就是我们在①中配置的ActionServlet 。不匹配这种格式的文件请求将不被Struts 处理。比如对*.html 或 *.jsp 文件的请求通常由容器内建的服务来处理。
④创建welcome 文件—不幸的是,在这里设置一个index.do 文件将不会工作。容器希望welcome 文件也是一个物理文件。在第3 章,我们展示了如何使用welcome 文件来转发到一个Struts action 。
⑤配置标签库—这里我们配置应用中使用的标签库。3 个核心的Struts 标签库—bean, html, 和logic— 将可用在大多数应用中。如果你的应用中使用了其它的标签库,它们也在此进行配置。第一个元素,,给出标签库的逻辑名称。这通常看起来像是一个文件路径,但其实不是。JSP 在导入标签库时将引用这个URI 。第2 个元素,, 提供提供了一个上下文相关的标签库描述符 (*.tld)路径。TLD 标识了库的实际类型(Java 类)。当需要这个库时,容器会搜索标签库类文件的 classpath 。对Struts 标签库来说,容器将在struts.jar 文件中找到这些包。
关于web 应用部署描述符的更多细节,请参见Java Servlet 规范 [Sun, JST] 以及书籍Web Development with JavaServer Pages[Fields] 。
4.2.2. ActionServlet 的参数
Struts ActionServlet 可接受多个参数,这些参数都总结在表 4.1 中。大多数参数在Struts
1.1 中都不赞成了,这样有利于提供模块化支持的新的配置包中的组件。
表格 4-1 ActionServlet 参数
参数 缺省值 说明 备注
config /WEB-INF/strutsconfig. xml 包含配置信息的XML 文件的上下文相关路径
config/${prefix} 使用指定的的前缀的应用模块的XML 配置文件的上下文相关路径。在多模块应用中可以根据需要重复多次 1.1 以后
convertNull false 一个参数,在组装表单时强制模拟Struts 1.0 行为。如果设置为true,数字的Java 包装类类型( 如java.lang.Integer) 将缺省为null( 而不是0). 1.1 以后
debug 0 调试的详细级别,控制针对这个servlet 将记录多少信息。接受的值为0 (off) 和1 (最不严格)直到6 (最严格)。大多数Struts 组件设置为级别 0 或者2
detail 0 用来处理应用配置文件的Digester 的调试详细级别。. 接受值为0 (off) 和1(l 最不严格)到6 (最严格).
validating true 标识是否使用一个检验XML 的解析器来处理配置文件(强烈推荐)。
application 无 应用资源束的名称,风格像是一个类名称。引用到位于名为resources 的包中的一个名为application.properties 的文件, 这里使用resources.application 。这种情况下,资源可以是classes 下的子目录( 或者JAR 文件中的一个包)。 不推荐;推荐使用 元素的 parameter 属性进行配置
bufferSize 4096 处理文件上传时输入文件缓冲区的大小 不推荐;推荐使用 元素的buffer-Size 属性配置
content text/html 每个响应的缺省内容类型和字符编码;可以被转发到的servlet 或者JSP 重写。 不推荐;使用 元素的contentType 属性配置
factory org.apache.struts.util.pr opertyMessageResource sFactory MessageResourcesFactory 用来创建应用消息资源对象的类名 不推荐;使用 元素的factory 属性配置
formBean org.apache.struts.action. ActionFormBean ActionFormBean 实现使用的Java 类名称 不推荐;使用每个 元素的class-Name 属性配置
forward org.apache.struts.action. ActionForward ActionForward 实现使用的Java 类名。 不推荐;使用每个 元素的className 属性配置
locale true 如果设置为 true,并且存在一个用户会话,在用户会话中存储一个合适的java.util.Locale 对象( 在Action.LOCALE_KEY 标识的标准关键字下) (如果还没有Locale 对象存在的情况下). 不推荐;使用 元素的locale 属性配置
mapping org.apache.struts.action. ActionMapping ActionMapping 实现使用的Java 类名 不推荐;使用每个元素的className 属性配置,或者使用模块应用的
元素的type 属性配置
maxFileSize 250M 文件上传时可以接收的最大文件尺寸(Byte) 。可以表示为”K”, “M”, “G” 。分别解释为kilobytes,megabytes, 或者gigabytes, 不推荐,使用 元素的maxFileSize 属性配置
multipartClass org.apache.struts.upload DiskMultipartRequestH andler MultiPartRequestHandler 实现l 类的全限定名称,用来处理文件上传。如果没有设置,禁止Struts 多部分请求处理
nocache false 如果设置为true,将在每个响应前加上HTTP 头。这样可以使浏览器对我们产生和转发的响应的缓存失效 不推荐;使用 元素的nocache 属性设置
null True 如果设置为true,那么如果使用了未知的消息关键字,应用资源将返回null 。否则, 将返回一个包含不愉快信息的错误信息 不推荐;使用 元素的null 属性配置
tempDir 提供给web 应用作为servlet 上下文属性的工作目录 处理文件上传时的工作目录 不推荐;使用 元素的tempDir 属性配置
4.3. Struts配置
Struts 配置文件 (struts-config.xml)用来装入多个关键的框架组件。这些对象一起构成了Struts 配置。
Struts 配置和 Struts ActionServlet 一起工作,创建应用的控制层。在这一节,我们将研究为什么需要Struts 配置。下一节,我们将讨论Struts 开发人员要如何来创建和维护配置。
4.3.1. 细节, 更多细节
Struts 配置是你的应用的真实蓝图。它知道表单中有什么字段。它知道哪里可以找到JSP 文件。它也知道应用执行的每一个Action ,以及每个action 需要的实际资源。
这看起来好像是把许多信息集中在了一个地方。实际上就是。但是通过将这些实现细节放在一起,许多开发人员会发现他们的应用更加易于创建和维护。
Struts 配置中的每个组件都是Java 对象。ActionForm 对象知道字段和表单。ActionForward 对象知道何处可以找到JSP 或其它资源。ActionMapping 则对象知道那个表单和转发将用于应用能理解的哪一个命令。
一个非常简单的应用可以在一个初始化内创建所有这些信息对象,然后设置需要的缺省值。例如:
但是,在实践应用中,初始化方法很快就会成为维护负担,并造成许多问题。具有讽刺意味的是,像这样的类并不涉及到多少编程问题。它只是从现有的类中实例化某个对象。它几乎用不着位于Java 代码中。事实上,它也不该位于代码中。Java 语言可以通过名称来创建一些给定的类。Java 也支持一些诸如可以决定一个类在运行时支持哪些方法的反射特征。
将这些特征结合在一起,其实并不需要一个Java 类。你需要的是一个文档来描述如何实例化一个Java 类使之成为一个全功能的对象。
当然,象Struts 这样的框架并不是唯一具有这个问题的东西。Servlet 容器基于同一原因也需要同样的东西。开发人员不得不告诉容器应用中需要什么servlet 以及其它一些对象。
他们不是编写一个Java 类并插入到容器之中,Sun 的工程师却是选择了使用一个XML 文档来配置的方式。容器读入这个文档并使用它来实例化和配置应用需要的servlet。
Struts 配置文件对Struts 来说就像部署描述符对容器一样。Struts 控制器读入配置文件并使用它来创建和配置框架需要的那些对象。
每个编写过部署描述符 (web.xml) 文件的web 开发人员都应该使用过XML 元素来创建一个Java 对象。例如,我们可以在web.xml 中部署一个servlet:
而下面则是我们在前面的Struts 配置文件中部署一个forward 对象的代码片段:
事实上, struts 配置并不是配置应用而是部署它。但大多数开发人员,还是很自然的将它这些对象视为是“配置,” 所以我们还是使用这个词汇。
4.3.2. 变更管理
按这种方式部署预配置的Java 对象是个强大的特征。当然,强大的功能也带来更大的责任。因为Struts 配置文件装入框架对象,所以它也对框架对象负责。
通过描述框架组件间如何交互,Struts 配置文件成为了一个管理应用变更的非常有效率的工具。实践中,配置文件要胜过一个简单的对象载入器,并被用作为动态的设计文档。
不难想象,可以用工具来读入Struts 配置文件并用它来产生和创建一个UML 图。现在有好多Struts GUI 都可以帮助你维护这个XML (参见4.4) 。不久就会出现可视化的工具可以帮助你维护由Struts 配置文件表达的架构设计2。
4.3.3. 受保护的变更原则
Struts 配置文件帮助你可以以最小的努力对应用变更作快速的反应。如果一个对象需要初始化为另一个值,你并不需要编辑,编译和部署一个Java 类。许多配置细节都涉及到表现层。团队中工作于该层的人员可能不都是Java 工程师。使用XML 文档可以使配置被页面设计员和项目管理者都能访问到。需要Java 工程师来创建和修改应用的基础对象,但配置这些对象却可以委派给其它人。实践中,我们常常将不经常的变更的东西—基础Java 类— 从经常变更的事物—Java 对象在运行的部署中分离开来。这就是受保护的变更原则(principle of Protected Variation [Larman]).
受保护的变更可以让我们记住一个的变更点至少可能产生一个的维护点。通常从基对象(不常改变)中分离出实现细节(经常改变),我们就可以减少维护应用要做的努力。
4.4. Struts配置元素
我们在第4.3 节中所讨论过,Struts 配置文件是一个用来部署Java 对象的XML 文档。配置中的每个元素对应一个Java 对象。当你在Struts 配置文件中插入一个元素,你就是告诉Struts 控制器在应用初始化时要创建一个Java 对象。如果从一个有一些示例性注释的空白的配置文件开始,可以很容易得将它修改后为你的应用所用。但是如果你只是遵循一些通用示例的话,也可能容易丢掉一些重要的特征。
大多数Java 开发人员都知道,如果他们需要关于Java 类的更详细的信息时,他们会查找JavaDoc。但是,你如何查找关于一个XML 文档的更多信息呢?
每一个良构的XML 文档, 包括Struts 配置文件,都包括一个描述该文档可用元素的指针。这就是文档类型定义 (DTD)。如果你看看struts-config.xml 文件的顶部,你就会发现这个元素: 这是告诉我们这个文档的DTD 的官方参考版本可以从所指定的URL 找到。在内部,Struts 使用来自于Jakarta Commons[ASF, Commons] 项目的Digester 来解析Struts 配置文件。Digester 使用struts-config DTD 来校验文档的格式,并且创建文档所描述的Java 对象。如果XML 文件包含了非正式文档化的元素,或者以非正式文档化的方式使用了元素,Digester 将不会处理这个文件。
2 译者注:这些常用工具包括: 1 各大公司的IDE, 比如JB, WSAD, Jdeveloper 等等 2 如果使用Eclipse 平台,有很多选择可用,包括 ObjectWeb 的lomboz, Myeclipse, IBM WTP,Eclipse
WTP(源于IBM WTP),Nitrox M7, Exadel Studio 等等。 你尽可以根据自己的需要进行选择。
如果基于某些原因,XML 校验产生了问题,你可以使用4.3 节所描述的validating servlet 参数将校验特性关闭。但我们不推荐这样做。
在内部,Struts 使用其自己的DTD 拷贝来处理配置。并不是每次在你的应用程序载入的时候都要从Internet 取回DTD 的参考版本。 (基于某些神秘的原因,一小部分开发人员说,将validating 设置为false 好像可以在没有Internet 连接的时候有助于应用的载入。通常,不管有没有Internet 连接你都应该设置validating=true 。)
表 4.2 总结了可以在Struts 1.1 中使用的配置元素。对Struts 1.1 新加的元素我们会简要说明。
表格 4-2 Struts 配置元素
元素 说明
data-sources 包含DataSource 对象(JDBC 2.0 Standard Extension) 的集合.
data-source 标识一个DataSource 对象,它可以被实例化,和进行配置,并在servlet 上下文中作为一个属性 ( 或者在application-scope 的bean 中).
set-property 标识一个额外的JavaBean 配置属性的方法名称和初始化值。
从Struts 1.1 global-exceptions 描述一个可以被Action 对象抛出的例外的集合
从Struts 1.1 exceptions 为一个例外类型注册ExceptionHandler
form-beans 描述这个应用模块中的form bean 描述符集合
form-bean 描述一个可以被元素引用的ActionForm 子类
从Struts 1.1 form-properties 描述一个 JavaBean 属性,可用来配置一个DynaActionForm 实例或者其子类
global-forwards 描述对所有Action 对象都可以作为返回值的ActionForward 对象集合
forward 描述一个可以被Action 作为返回值的ActionForward 对象
action-mappings 描述一个可以用来处理匹配ActionServlet 注册到容器的url-pattern 格式的请求的ActionMappings 对象集合
action 描述一个ActionMapping 对象, 可以用来处理一个对特定的模块相关的URI 的请求
从Struts 1.1 controller 描述一个封装了应用模块运行时配置的控制器配置bean
从Struts 1.1 message-resources 描述该模块的消息模板一起配合使用的消息资源MessageResources 对象
从Struts plug-in 标识一个通用应用的plug-in 模块的全限定类名,它接受
1.1 应用的启动和退出事件的通知
为了更方便,附录B 还以标准的API 格式列出了struts-config DTD。在这一节,我们会讨论这些元素并提供一些使用示例。关于每个元素及其接收的属性的具体细节,请参考附录B。
如上所述,现今许多编成组件都以XML 文件的方式进行配置,包括Java servlet 容器。关于Java 和XML 的更多知识,我们推荐J2EE and XML Development [Gabrick]这本书。
4.4.1.
在一个Struts 应用中,ActionServlet 位于调用树的最顶层,但其实际工作会委托给Action 对象。这种分而治之的策略在许多环境下都工作的很好,例外会被进行例外处理。许多应用喜欢用一致的方式来处理例外,但这会在多个Action 中复制例外处理代码。
为了在全部Action 对象中进行一致的例外处理,你可以在一个Struts 配置文件中注册一个ExceptionHandler 。框架提供了一个缺省的 ExceptionHandler (org.apache.struts.action.ExceptionHandler) 它可以在一个请求范围的属性下保存例外,为例外信息创建 ActionError 对象,并转 发控,制到JSP 或其他你选定的URI。Struts 标签会自动输出你的例外信息的本地化版本。所以,你可以使用同一个页面来显示你想用来显示的校验错误的例外错误信息。
如果你还需要做些其他的事情,ExceptionHandler 可以被子类化而加入新的行为。如果需要的话,每个例外都可以标识其自己的句柄类。
你可以为一个例外注册一个全局句柄以及针对某个ActionMapping 的局部句柄。要注册一个例外,你需要提供Exception 类型,消息关键字,以及响应路径,如下所示:请参见第9 章,关于如何编写你自己的例外处理句柄。
4.4.2.
Struts ActionForm (org.apache.struts.action.ActionForm) 提供了一个方便的保存通过HTTP 请求提交的输入属性的方法。但是为了保存输入属性,控制器必须首先创建一个ActionForm 并将其保存在请求或者会话的上下文中,在这里,可以被其他框架组件—比如JSP 标签—所找到。
如果在输入页面上有多个表单,那么每个表单都需要其ActionForm 对象有不同的属性(Attribute)名称。因此,你不能仅使用标准的命名。因为bean Attribute 名称是其公共API 的一部分,我们应该能提供开发者友好的ActionForm 命名,比如logonForm 之类。
某些特别的ActionForm ,比如 DynaActionForm (org.apache.struts.action.DynaActionForm),需要在它们被创建时传递额外的属性(property)。所以,我们也需要有地方来放置这些元素。ActionFormBean (org.apache.struts.action.ActionFormBean)通过将之存储为一个ActionForm 对象描述符来解决了所有的这些问题。每个ActionFormBean 都有描述一个ActionForm 特性名称和类型的属性。ActionFormBean 也包含 property 特性,可以在DynaActionForm 中使用。
Struts 配置文件提供了一个 元素来归类一个模块所使用的各种ActionFormBean 。每个ActionFormBean 都由一个相应的 元素创建。在运行时,控制器调用适当的ActionFormBean 来找出哪一个ActionForm 对象被创建,在哪里存储它,以及要使用什么属性(Attribute)名称。
下面是一个针对常规ActionForm 的配置,以及一个DynaActionForm 的 元素配置:
menuForm 表达了一个常规的ActionForm 子类;它要求一个对应的Java 类支持。logonForm 并不要求使用一个特别的子类,但可以使用DynaActionForm。(DynamicActionForm 从Struts 1.1 开始引入)
请参见第5 章获取关于ActionForm 的更多信息,包括DynaActionForm 。
4.4.3.
通过集中管理细节,Struts 配置将变更予以最小化。当环境改变时,多数实现细节可以通过配置来进行修改,而不用改动Java 或者 JSP 源代码。
Web 应用中一个令人痛苦的细节处理就是URI [W3C, URI]。多数URI 都直接映射到应用目录树中的物理文件。这对常规的站点来说还比较容易。要将 “一个页面放到web 上,”你只需要将页面存储到站点的某个目录。而目录已经映射到站点的公共URI, 不需要配置其它地方。
发布web 页面其实就是传输文件。这其实很简单,直到你想删除么某些页面或者使用不同的页面。当这些事情发生了,(实际上它们经常发生), 你不得不更新应用中所有对该页面的引用之处。如果漏掉了一些,某些地方仍然引用到旧的页面,你就会遇到我们的数据库人员所称的“异常更新”(update anomaly)。两个假定为相同的情况现在都不同了。数据库对这个问题的解决方案是规格化(normalization.) 我们将情况存放进一个表,而每个人都从这个表中进行查找。如果情况改变,我们仅仅需要更新情况表,每个人都会被带到相同的页面。
Struts 处理 URI 表的方法是ActionForward。一个ActionForward 对应一个URI 的逻辑名称。其他组件可以引用这个名称,而不需要知道任何有关 URI 的情况。如果URI 改变,我们只需要改变它的ActionForward。
其他组件通过请求ActionForward 的路径来得到更新过后的 URI。这样,通过封装实现细节到逻辑名称之后,我们最小化了变更并减少了潜在的错误。
ActionForward 的主要使用者是Action 对象。当一个Action 完成时,它返回一个ActionForward 或者null 。如果 Action 没有返回null,ActionServlet 就将控制转发到返回的ActionForward 的路径。典型地,Action 将通过名称查找ActionForward ,而不需要知道关于URI 的任何事情。你可以部署全局转发Global ActionForward 在 元素中,像这样:
这些 forward 对应用中的每个Action 都有效。你也可以部署一个局部 ActionForward 到 元素中。局部转发仅针对该ActionMapping 有效。
关于ActionForward 参见第6 章。
4.4.4.
ActionForm 负责保存应用需要收集的数据。ActionForward 归类那些应用需要引用的URI。ActionMapping 则描述应用要采取的操作、命令。
Action 对象处理操作的实际工作。但大量的管理细节都关联到一个操作。ActionMapping 就是用来包装这些细节的。
一个重要的细节之处就是用来调用Action 对象的URI [W3C, URI]。Action 的URI 被用作一个ActionMapping 的逻辑标识符,或者路径。当web 浏览器请求一个Action 的URI, ActionServlet 首先查找相应的ActionMapping 。ActionMapping 则告诉 ActionServlet 哪个 Action 对象要用于这个URI。
除了URI 路径和Action 类型以外,ActionMapping 还包含了几个可以用来在Action 被调用时发生的行为的属性。改变这些属性会改变Action 对象的行为。这可以帮助开发人员使同一个Action 对象有更多的用途。如果没有ActionMapping 对象,开发人员可能需要创建比现在多得多的Action 类。
你也可以使用ActionMapping 来简化到另一个路径的转发或者重定向。但绝大多数情况下,它只是用来连接Action 对象。
元素描述了我们的应用要用来处理请求的ActionMapping 对象(org.apache.struts.action.ActionMapping) 的集合。请求要到达应用然后到达ActionServlet ,它必须匹配上下文和我们在容器中注册的url-pattern 格式。
因为所有的请求都匹配匹配这个格式,我们就不需要使用上下文或者url-pattern 来标识一个ActionMapping 。所以如果URL 是
我们只需要引用/myAction 作为ActionMapping 的路径。每个 ActionMapping 都由对应的嵌入到元素中的 元素创建,如下所示:
一个ActionMapping 可以引用多个属性。紧随Action 对象之后,ActionMapping 可能是Struts 应用另一个最重要的对象。
关于ActionMapping 的详细信息,参见第7 章。
4.4.5.
Struts 允许多个应用模块共享一个单一的控制器 servlet。每个模块有其自己的Struts 配置并且可以相对于其他模块独立开发。 元素允许每个模块为ActionServlet 标识一套不同的配置参数。它们大多数是部署描述符中的原始设置。
元素设置的属性值存储在一个控制器配置bean (org.apache.struts.config.ControllerConfig) 之中。每个应用模块要创建一个控制器配置,包括缺省的根模块。如果一个模块的 struts-config 提供了一个 元素,就是用来设置模块的控制器配置bean 的属性。
因为各个模块共享ActionServlet, 你也可以为每个模块插入不同的请求处理器。这可以使每个模块都按自己的方式处理请求,而不用子类化共享的servlet。
下面是一个 元素的配置例子,它设置nocache 和null 配置属性为true 并且装入一个定制的请求处理器: 请求处理器是ActionServlet 处理循环的核心。大多数情况下,你可以编写和装入一个请求处理器,来代替创建你自己的ActionServlet 子类。关于ActionServlet 和请求处理器的更多信息,参见第9 章。
4.4.6.
每个模块都应该有其自己的缺省消息资源束。这是一个Struts 组件,如JSP 标签, 在没有其他特别标明的情况下要使用的资源束。你也可以装入其它额外的资源束,连同特定的消息模板。例如,许多开发人员喜欢将图像相关的消息放在一个单独的资源中。
元素用来部署应用需要使用的资源束。下面是一个 元素的例子,它为模块部署了缺省的资源束,另一个则部署了一个图像消息的资源:
在需要时,框架会在名为resources 的包中的名称为application.properties 的文件中寻找缺省的消息资源束。包,或者文件文件夹,可以在容器的classpath 路径的任何地方。典型地,资源束也可以以JAR 文件的方式,或者放在WEB-INF/classes 文件夹中。
如果 JSP 标签,或者其他组件,标识了resources.image 资源束,框架会在resources 包中查找名为image.properties 的文件。
参见本章4.5 节,获取关于消息资源束的更多信息,以及第13 章如何本地化应用。
4.4.7.
对Action 来说, 需要特别的资源来完成其工作的情况并不常见。不过,它可能需要使用一个非数据源兼容的连接池。或者也许需要创建一个应用bean 来为表单使用。也许需要读入自己的配置文件来创建一系列的对象,就像struts-config 所做的一样。在一个常规web 应用中,这些任务通常委托给一个特殊的servlet。在Struts 应用中,我们倾向于将这些任务委托给Action 。当一个Action 需要初始化和销毁它自己的资源时,它可以实现PlugIn 接口(org.apache.struts.action.PlugIn)。这个接口声明了init 和destroy 方法, 控制器可以在适当的时候进行调用。
PlugIn Action 可以在Struts 配置中通过元素进行注册。下面是一个标准的plug-in ,用来初始化Struts Validator: 请参见第9 章获取关于ActionServlet 和PlugIn Action 的更多信息。
4.4.8.
虽然Struts 框架是模型中立的,它仍然需要和业务层甚至数据访问层进行交互。一个组件期望调用者给它传递一个活动的SQL 连接(java.sql.Connection)的情况并不是不常见。这也使调用者(比如Struts) 有责任管理连接的生命周期。为了向应用提供在连接到数据访问组件时更多的灵活性, JDBC 2.0 标准扩展包提供了一个基于工厂的方法来获取数据。对一个应用连接到数据库,或者其他数据服务的首选方法是使用一个实现数据源接口(javax.sql.DataSource)的对象。
在一个web 应用中,一个数据源对象通常代表一个应用中所有用户都可以共享使用的连接池。获取一个数据库连接可能在实践和资源上都有很昂贵的代价。典型地,web 应用以一个单独的账户登录到数据库中,然后自己管理这个单独账户的安全性。
为了帮助开发人员使用连接, Struts 提供了一个数据源管理组件。你可以使用这个组件来实例化和配置一些实现数据源的对象,并且可以从JavaBean 的属性进行整体配置。
如果你的数据库管理系统没有提供满足这两个要求的组件,你也可以使用Jakarta Commons 数据库连接池基本数据源类(org.apache.commons.dbcp.BasicDataSource)。在Struts 1.1 中,Struts 通用数据源(org.apache.struts.util.GenericDataSource) 是一个BasicDataSource 类的包装类。(这个Struts 类已经不推荐了,仅提供向后兼容之用)。
如果你的数据库管理系统提供了它自己的数据源可供Struts 使用,你就应该考虑使用这个实现。在Struts 中使用BasicDataSource 或者 GenericDataSource 并不比使用其它类更有效率。要根据你的环境选择最好的实现。
你也可以配置不止一个数据源,然后根据名称进行选择。这个特征可以提供更好的安全型和扩展型,或者用一个数据源实现和另一个进行比较。
下面是一个数据源配置,使用MySQL 数据库的Struts 缺省配置: 不像其他struts 配置元素, 元素非常依赖于 元素。因为开发人员经常需要配置他们自己的DataSource 子类,所以只有较少的属性内建到了元素之中。
数据源对象是Struts 和数据访问层之间的桥梁。而配置中的其他组件组成了Struts 的控制层。
4.4.9. 该你了
如果你子类化了一些Struts 配置对象,你可以使用元素传递自己的属性到这些子类之中。这就使你可以扩展Struts 框架类,而不用改变配置文件的解析方式。下面是一个例子,它传递一个XSL 样式表引用到一个 (假定的) ActionForward 对象的定制实现:
当logon 元素的XslForward 对象被实例化时, Digester 相当于调用
你也可以在很多Struts 配置元素中使用这种方法,使所有的对象都成为完全可插入的。
4.4.10. Struts config 骨架
清单 4.2 是一个Struts 配置文件的骨架,展示了最常用的元素和属性。这个文件也和Struts 空白应用中的配置文件非常相似:
清单 4.2 Struts 配置骨架
完整的Struts 配置元素和属性清单,参见附录B,struts-config API 。
4.5. 应用资源文件
Struts 框架提供了好用和灵活的消息系统。我们在第3 章接触过这个系统,在第13 章还要详细讨论它。在这一节,我们需要用来使系统运转的配置文件。
在4.4.6 节,我们看到了如何告诉Struts 在何处找到资源束。在这一节,我们要讨论如何创建资源束。消息的文本被存储在一个标准的Java 属性文件 (java.util.Properties) 之中。
在Java 和JSP 代码中,要给定一个消息的关键字;消息文本在运行时从Property 文件中检索。框架文档将消息属性文件引用为application resources 或者message resource bundle 。
如果你想要本地化你的应用,你可以为你想要支持的场所创建一个额外的应用资源文件。这实际上是创建一个资源束(java.util.ResourceBundle) 。框架会为每个用户维护一个标准的Locale 对象(java.util.Locale) 。针对用户场所的合适的消息会自动从资源束中进行选取。关于本地化的更多信息,参见第13 章
属性文件自身是一个普通的文本文件,每一行是一个关键字-值对。你可以使用任何文本编辑器进行编辑,包括Windows Notepad 。
应用资源文件的缺省名称是通过在web.xml 向Struts ActionServlet 传递一个初始化参数决定的。下面这个片断,参数的名称是application:
这个参数没有缺省值。在应用中使用Struts 应用资源束之前必须首先进行配置。应用资源文件位于应用的CLASSPATH 之中,这样Struts 可以找到它。最好是放在你的应用的classes 文件夹中。这可能是在WEB-INF/classes 文件夹中,或者,如果你以二进制部署你的应用时,则在WEB-INF/lib 下的一个JAR 文件中。
param-value 应该是你的文件按包命名格式的全限定名称。这意味着如果如果你将资源文件直接放在classes 下,你可以直接使用文件名,如前面的代码片断所示。
如果你将文件放在一个子目录中,那么该子目录就相当于一个Java 包。如果应用资源束在一个名为resources 的子目录下,你就应该这样来标识:
物理文件的系统路径应该是:
如果你将类移到了JAR 中,不需要进行什么改变。Struts 可以在 JAR 文件中找到资源束,就如找到其他类一样。为了本地化你的应用,为每个支持的场所添加资源文件,并修改基本名称:
WEB-INF/classes/resources/ application.properties application_es.properties application_fr_CA.properties
Application 名称只是一个习惯。对框架来说没有缺省设定。你可以将名称改为你认为适合的任何名字。另一个常用的缺省是使用appplicationResources 作为名称, 因为它在一些早期的Struts 例子中经常使用。
关于更多属性文件和资源束的信息,参见Sun Java 教程,以及本书地13 章的国际化[Sun, i18n]部分。
本章稍后表述的Ant 构建文件通过自动将资源束从源代码树中拷贝到二进制class 文件夹中来在构建应用时帮助你管理应用资源束。这可以将原始文件和其他源代码放在一起。
4.6. Ant构建文件
虽然不是使用和配置Struts 需要的严格要求的部分,许多开发人员还是使用Ant 及其构建文件来装配,部署,甚至测试他们的应用。我们的logon 应用 (第2 章)中的build.xml 文件就是基于空白Struts 应用中提供的一个实际框架。
构建文件设置为使用源代码存储在WEB-INF 子目录下的项目树。这使得整个应用,包括源代码和编译文件,都集中在一个目录系统之中。这就能使你得应用的工作目录可以位于你的开发服务器中。如果容器可以很好的重装类文件,你就可以重新构建应用来测试最新的改变,而
不用重启容器。这个build.xml 希望的源代码书结构请参见第4.3 节。清单4.3 展示的是我们的一个简单的完整build.xml 文件。
清单 4.3 Ant 的 Build.XML
1 project 给出一个构建文件的总体名称,并且标识一个基础目录和缺省目标。当Ant 装入文件时,目标会首先锁定它的调用。要使用不同的目标,改变这个缺省设置并存储文件,或者在命令行中覆盖它。缺省基准目录设置为build.xml 的当前目录。脚本的其他部分这是WEB-INF 文件夹,并且要在这个基础目录的子目录下查找源代码。这个块中还有一些属性要设置,以备后用。要让这个文件用于另一个应用,你可以只修改这些属性,而让剩下的其他属性保持原样。
○
2 path 块建立了Ant 构建应用是要使用的classpath 。它每次都会执行而不管是选择哪一个目标。通常,这是一个WEB-INF/lib 文件夹中的JAR 的清单。
○
○prepare 帮助Ant 通过比较类文件和源文件的时间戳来最小化编译工作。
○resources 目标从源代码树中拷贝一些属性文件 (java.util.Properties) 到classes 树。这
3
4
样你可以保持原始的属性文件和文件源代码中的保持一致。
5 compile 目标首先调用prepare 和resources 目标,然后开始构建源文件。Jikes [Jikes]或者标准的javac 编译器都可以使用。
○
6 clean 目标通过删除和恢复类文件夹来确保所有的东西都重新构建。
○
○javadoc 目标为应用构建JavaDoc。通常,你需要象标明项目的classpath 一样为
7 JavaDoc classpath 标明相同的JAR 路径。注意,这是一个冒号分隔的列表。JavaDoc 编译器会发出警告,但会继续为它能找到的类产生文档。
8 dist 目标为应用创建一个Web 归档(WAR) 文件。这个文件可以用来在你的生产服务器上部署你的应用。
○
○project 目标将全部构建所有东西,并准备一个二进制的分发包。
9
关于Ant 得更多信息,我们强烈推荐你阅读Java Development with Ant[Hatcher] 。
4.7. 配置 Struts 核心
当此为止,我们已经全部涉及了要使你的Struts 应用运行需要构建和定制的四个文件。
部署描述符 (web.xml)
Struts 配置文件 (struts-config.xml)
应用资源束 (application.properties)
Ant 构建文件 (构建.xml) 现在,我们把它们结合起来,作为一个Struts 配置的检查表。
4.7.1. 安装Java 和Java servlet 容器
第一步是安装一个servlet 容器,比如Tomcat 。我们在第1 章讲述过这个内容,但现在是 一个让你能从头开始的快速检查表: 从JavaSoft 站点[Sun,Java] 下载并安装Java 1.4 (或更高版本)。
从Jakarta [ASF, Tomcat] 下载并安装Tomcat 4 LE ( 或更高版本)。 当然,Struts 也可以工作于其它web 容器和其他 Java 虚拟机。这仅仅是我们的一个建议。 Struts 分发包中包括配置各种容器的技术规范和注意事项。
4.7.2. 安装开发环境
我们在第3 章也涉及了安装开发环境。Struts 在大多数 Java 环境下都能工作的很好。如果 你还没有一个好的环境,作为入门比较好的选择是jEdit 和Ant: 下载并安装Ant 1.4 (或更高版本) [ASF, Ant]. 下载并安装jEdit [jEdit]. 安装Ant add-in for jEdit 但是再次提醒,这仅仅是建议。如果你已经有一个开发环境了,它也会工作的很好。
4.7.3. 安装Struts 核心文件
运行Struts 需要的常备文件都在Struts 库文件分发包(jakarta-struts-1.1-lib.zip) 中提供了。这些包括几个JAR, 标签库描述符,DTDs,和标准的XML 配置文件。这些常备文件和你要提供的4 个配置文件一起,创建了一个核心的Struts 配置。
下面是一个检查表:
下载并解压Struts library distribution [ASF, Struts].
拷贝所有的*.jar 文件到应用的/WEB-INF/lib 文件夹.
拷贝所有的*.tld 文件到/WEB-INF 文件夹.
拷贝所有的*.xml 和*.dtd 文件到/WEB-INF 文件夹.
创建部署描述符( 4.2).
创建Struts 配置文件(4.4).
创建资源束( 4.5).
创建Ant 构建文件(4.6).
4.7.4. 配置Tiles框架
Tiles 是一个Struts 框架的可选组件,是一个强大的页面组装和布局工具,在其意义上是一个真正的框架。我们在第11 章讨论Tiles 的使用。使用Struts 框架的其它部分时并不需要使用和配置Tiles 。但是如果你喜欢Tiles,这就是一个练习。
你使用Tiles 的所需的所有文件都在Struts library distribution 中提供了( 4.7) 。如果你让你的应用基于Struts 空白应用(4.10)或者你已经安装了所有必需的Struts 库文件夹到应用的
/WEB-INF 或者r /WEB-INF/lib 文件夹中,那么基本的所需文件已经有了。下面是检查表:
从Struts lib 文件夹拷贝struts-tiles.tld 和 tiles-config.dtd 文件 (如果没有)到/WEB-INF 文件夹.
插入下面的语句块(如果没有)到 /WEB-INF/web.xml 文件中,并且紧跟其它 元素:
创建一个空白的tiles-defs.xml (如果没有)在 /WEB-INF 文件夹中,像这样:
插入这个 元素到struts-config.xml 中,位置在关闭的 元素之前:
至于能运行的具体Tiles 应用的例子,请参见Struts 分发包中的Tiles 示例应用,以及第16 章我们要讨论的Artimus 1.1 示例。Struts 空白应用 ( 4.10) 其实也配置了Tiles 。
至于Tiles 应用的Struts 1.0 版本,参见第15 章的Artimus 1.0 示例。
4.8. 配置Struts Validator
像Tiles 一样,Struts Validator 也是框架的一个可选组件。
我们会在第12 章涉及Struts Validator 。使用Struts 框架的其他部分时并不需要使用和配置Validator 。不过如果你喜欢,这也是一个练习机会。
你使用Validator 所需的所有文件都在Struts library distribution 中提供了( 4.7) 。如果你让你的应用基于Struts 空白应用(4.10) 或者你已经安装了所有必需的Struts 库文件夹到应用的/WEB-INF 或者r /WEB-INF/lib 文件夹中,那么基本的所需文件已经有了。
下面是检查表:
从Struts lib 文件夹拷贝struts-validator.tld 和 validator-rules.xml 文件 (如果没有)到/WEB-INF 文件夹.
插入下面的语句快到(如果没有)到 /WEB-INF/web.xml 文件中,并且紧跟其他 元素:
创建一个空白的validations.xml ( 如果没有)在 /WEB-INF 文件夹中,像这样:
插入这个 元素到struts-config.xml ,位置在关闭的 元素之前:
至于能运行的具体Validator 应用的例子,请参见Struts 分发包中的Validator 示例应用,以及第16 章我们要讨论的Artimus 1.1 示例。Struts 空白应用 ( 4.10) 其实也激活了Validator。至于Validator 应用的Struts 1.0 版本,参见第15 章的Artimus 1.0 示例。
4.9. 从空白Struts应用开始
Struts 分发包中的Struts Blank 应用提供了开发新应用时可以采用和修改的骨架配置。它包含了来自于分发包中的所有的基础文件以及开发人员应提供的四个配置文件的初始版本
( 4.7),以及Tiles 和Validator 的骨架配置。Struts Blank 是以一个WAR 文件的形式分发的。开始时你需要做的是:
从二进制分发包中的webapps 文件夹拷贝struts-blank.war 文件到容器的WAR 部署目录(通常是webapps).
将struts-blank.war 更名为你想要的应用名称,比方说myApp.war.
启动或重启servlet 容器 Struts Blank 应用就会以你的新应用名称进行部署。如果你访问缺省页面:
你的新应用就会显示一个简单的欢迎页面。
Blank 应用并没有包括一些Java 源代码文件—这是你的工作—但它的确包含了一些有用的文件和页面,我们总结在表 4.3 中。
Struts Blank 应用设计目的是让你可以很容易地开始一个Struts 项目。如果将它部署在一个servlet 容器的本地拷贝,比如Tomcat 或者Resin, 你就可以马上在上面工作了。构建文件的目的是为了使你在过程中可以就地工作,只是需要时重启容器或者重新装入应用。
如果你正在一个团队内工作, 你可能需要使用一个不同的方案, 因为你需要随时将文件Check in 或者Check out 。但是简单的事情总归简单,Struts Blank 应用使得开始构建一个新的Struts 应用真正变得非常简单。
表格 4-3 Struts Blank 起始文件
文件名 目的
/index.jsp 一个常备的欢迎页面,它转发到一个Struts Welcome action.
/pages/Welcome.jsp 一个欢迎JSP , 通过一个Welcome action 访问
/classes/resources/application.properties 部署的应用资源文件。这是一个运行拷贝,原始文件和其他源代码在一起
/WEB-INF/struts-config.xml 一个起始 Struts 配置文件,常用元素有示范性说明
/WEB-INF/tiles-def.xml 一个起始 Tiles 配置文件,常用元素有示范性说明
/WEB-INF/validator-rules.xml 一个起始标准 Validator 配置文件,设置基本的validator 。
/WEB-INF/validations.xml 一个起始Validations 配置文件可以在此描述你的form 。
/WEB-INF/*.tld Struts 标签的标签库描述符文件。
/WEB-INF/lib/*.jar 框架类依赖的JAR 文件
/WEB-INF/src/build.xml Ant 构建文件.
/WEB-INF/src/java/ Java 源代码文件的起始目录
/WEB-INF/src/resources/application.proper 原始的application.properties 文件。编辑后要重新构建
ties
需要注意的一件事情是build.xml 文件引用的本地系统路径可能存在或者不存在。
jdbc2_0-stdext.jar 和 servlet.jar 需要用来产生JavaDoc 。Blank build.xml 会在你的默认驱动器的/javasoft/lib 文件夹下查找这些文件。如果必要,你可以修改这些设置以指向你保存这些文件的地方。
你的容器应该包含其所支持的servlet API (如, 2.2 或2.3)的servlet.jar 。
Tomcat 4 在其$TOMCAT/common/lib 文件夹中保存servlet.jar 文件。
jdbc2_0-stdext.jar 包含在Struts 库文件分发包中。它没有和Struts web 应用绑定在一起。许多容器,如Tomcat , 会共享这个文件的一个拷贝。在WEB-INF/lib 文件夹中放置另一个拷贝可能会造成冲突。
其他目录是保存你的一个WAR 文件的地方。这可以用来在开发完成之后在生产系统上部署你的应用,或者在准备测试的时候也行。再一次提醒,你可以修改路径或者创建目录。Blank build.xml 工厂设定是默认驱动器上的/projects/lib 文件夹。
4.10. 配置模块化应用
Struts 架构的一个关键优点是所有的请求都通过一个单一的控制点。开发人员可以集中精力于那些应用于每一个请求的功能,并且避免整个应用中的代码重复。因为Java 是一个多线程平台,Struts 使用一个单独的控制器 servlet 也提供了最好的性能可能性。开发人员编写更少的代码,机器在更少的资源下更快的运行。一切都很完美。
在Struts 1.0 中,应用以单独模式运行。Struts 配置文件对用户来说是一个。如果多个开发人员工作于一个应用,他们需要有一个方法来管理Struts 配置的更新。
在实践中,开发人员倾向于将他们的工作分割为逻辑单元,这非常类似于他们将Java 代码分离到各个包中。团队成员在应用中有他们自己的名字空间的情况并不是不常见。
在一个在线拍卖应用中,一个团队可能工作于registration 模块; 另一个团对可能工作于bidding 模块。第1 个团队可能具有一个/reg 文件夹来存放他们的JSP 页面以及一个app.reg 包来存放他们的Java 代码。同时,团队2 可能有一个/bid 文件夹存放JSP 页面以及一个app.bid 包来存放Java 代码。在资源文件中,每个团对可能都有他们以reg. 或 bid. 为前缀的关键字。
当然,这种方式并不是只可在大型团队中组织大型项目。许多单独的开发者也做同样的事情。限制一个文件夹中的文件数量和包中的类数量,被认为是很好的项目管理。
许多开发人员也按逻辑模块来组织项目,而不管是否需要共享文件。
4.10.1. 分而治之
在Struts 1.1 中,将应用分为模块的理念成为了一种习惯—现在已经集成到框架中了。让我们回头看看,Struts 是如何将应用组织为模块的。
web 应用容器是我们可以为每个应用创建上下文来共享服务。这个上下文对应于服务器的webapp 目录的一个子目录。按同样的道理,Struts 1.1 通过为每个应用创建一个前缀来共享应用的使用。多个模块可以运行于相同的应用空间,每一个都在起自己的前缀之下,与多个应用可以运行于同一个服务器空间非常相似—每一个都有其自己的上下文。
我们在编写web 应用时,我们经常引用到上下文-相关的 URI。这是一个不包含应用名字或上下文的路径。同时,我们在编写Struts 应用时, 我们也经常应用一个模块-相关的URI。不用惊讶,这也是一个路径,不包含模块名称,或者模块前缀。表 4.4 所示的是关于绝对的,上下文相关的,和模块相关的同一个URI 的比较。
就像你可以编写一个web 应用,并将它配置在某个上下文中一样,你可以编写一个Struts 应用模块并配置它在某个前缀下运行。
编写一个模块和编写一个独立运行的应用并没有多大的不同。
所有世纪的配置都在部署描述符中。如果你将某个模块从某个前缀移动到根,或者从根移动到某个前缀下,或者从一个前缀移动到另一个前缀,模块中没有JSP,Java 代码,或者XML 代码需要改变。
要设置一个应用来使用分离的reg 和bid 模块,我们可以这样配置servlet 描述符:
表格 4-4 表 4.4 Absolute, 上下文-relative, and 模块-relative portions of the same URI
URI 类型 URI
绝对URL http://localhost/myApp/mymodule/myAction.do
域-相关 /myApp/mymodule/myAction.do
上下文-相关 /mymodule/myAction.do
模块-相关 /myAction.do
在这个例子中,reg 团队可以工作在struts-config-reg.xml 而bid 团队可以工作在struts-config-bid.xml 配置。每个团队都工作于他们自己的模块,就像她们工作于一个单模块的应用一样。框架做了有关模块前缀的所有调整,就像容器为应用上下文所作的调整和配置一样。
对,几乎是所有的调整…
4.10.2. 给页面加前缀
当框架针对模块前缀调整了URI, 它会调整所有URI, 不管它是指向一个ActionMapping 或者是模块中的其他资源,如JSP。在struts-config-reg.xml 文件中,我们可能有一个模块相关的URI,比如/input.do 。则该URI 的上下文相关版本就成为/bid/input.do 。同时,我们可能有一个到/pages/Index.jsp 的引用,那么该引用的上下文相关就成为/bid/pages/Index.jsp 。
迁移ActionMapping 是非常容易的,它们实际上是虚拟的。但是许多URI 引用到JSP,它们实际上和物理文件相关。其它URI 也可能引用到HTML 页面,图像文件等等。
这意味着虽然bid 团队可以在Struts 配置中忽略模块前缀,但是他们仍然需要知道,他们是在使用哪一个前缀,这样才知道应该在哪里存放他们的文件。如果前缀改变,需要重新命名那个子目录。不需要修改JSP, Java, 或者XML 编码,尽管如此,他们必须使他们的页面目录名称和模块名称保持同步。
这其实和我们要在应用层次要干的事并没什么不同。如果我们上载文件到应用中,我们需要知道其应该存放的上下文目录。如果我们上载文件到模块,我们就需要知道他在哪一个模块目录下面。
4.10.3. 修改配置
如果你已经你已经有了一个设置为类似一个模块应用的Struts 1.0 应用,诀窍就是使模块前缀从模块的配置文件中分离出来。
如果页面已经在以模块名称命名的子目录中,它们继续留在那里就可以了。如果不是,你也能够将它们移动到模块目录下面,而不用作任何改动 (当然,除非一些硬编码的连接,比如 标签,必须修改)。
4.10.4. 共享Struts JAR
如果你的容器支持这个功能,Struts JAR 可以被web 容器中的所有应用所共享。 (现在来说多数都行或者即将行)。请参考你的容器的文档,看如何配置共享的JAR。大多数情况下,你可以简单地将Struts JAR 放在共享的lib 文件夹下面,然后在/WEB-INF/lib 文件夹下删除它们既可。
对Tomcat 4 来说,共享库文件夹位于
对缺省的Windows 安装,这可能是对应于\Program filess\Apache Tomcat 4\common\lib 。当然,这意味着所有共享这些JAR 的应用必须是同一版本的Struts 应用。
4.11. 小结
没有一个应用应该是孤岛。要将应用的所有组件集合在一起工作,你必须创建并维护一些配置文件。要使一个Struts 应用建立并运行,需要开发者提供一个Struts 配置文件,一个资源文件, web 应用部署描述符文件,以及一个可选的Ant 构建文件。本章一步步讲述了创建这些文件的细节。
Struts 配置的一个关键优点是它集中了变更管理。因为实现细节被集中了,Struts 应用就可以从Struts 配置进行全面重新配置,而不用去进行一些修改Action 类或者表现页面的工作。
所有的组件都由Struts 配置进行初始化—ActionForm , ActionForward ActionMapping— 它们形成了Struts 控制器的核心。组合在一起,这些对象表达了 应用,的外部和内部API —剩下的就是具体的实现细节了。这些核心组件制定了应用能接受的输入,要转发的地方,以及要做的事情。
那么,接下来是什么呢?
本书的第2 部分,我们会深入到每一个核心组件来帮助你全面了解它们。在第3 部分,我们集中于你的应用的可见部分:页面。第4 部分, 会主要用几个实例研究来使用1 到3 章所表述的技术。
但是如果你已经非常渴望想要开始了, 你如今应该已经有足够的知识可以开始构建你的Struts 应用了。而且,如果你喜欢,就象本书剩余部分所展示的,你可以使用我们介绍的新
技术重构,改进,或者扩展你的现有应用。
Leave a Reply
You must be logged in to post a comment.
近期评论