第 章 基础 学习目的与学习要求 学习目的:深入了解Struts2框架,掌握Struts2框架的 工作流程及各个配置文件,Action类的开发及配置,Model组 件的配置开发和View试图组件的配置跳转。 学习要求:熟练应用开发工具搭建和开发基于Struts2 框架的应用系统;熟练开发Action类及配置调用,正确使用 View试图组件跳转显示,顺利完成本章节案例开发,并模拟开 发其他项目功能。 本章主要内容 本章主要内容包括MVC模式概述、MVC与Struts2的 映射、Struts2框架的工作流程和配置文件、Action类的开发 和配置、Model组件和试图组件的开发和配置及Struts2开发 步骤。 在Web应用开发中,我们经常使用Struts框架解决用户 接口(UI)层,及其与后端应用层之间的交互。 Struts是CraigMcClanahan在2001年发布的Web框 架。经过多年的验证,Struts越来越稳定和成熟。目前, Struts推出2. 0版本的全新框架,它在另一个MVC框架 Webwork的优良基础设计之上进行了一次巨大的升级。 Struts框架是MVC设计模式的一个具体实现,下面介绍 MVC模式。 3.MVC模式概述 1 在计算机软件工程领域常常提到设计模式(Design Patern)。那么,什么是模式(Patern)呢? 一般来说,模式是 指一种从一个多次出现的问题背景中抽象出的解决问题的固 定方案,而这个问题背景不应该是绝对的,或者说是不固定 第3章 Struts基础 的。很多时候,看来不相关的问题,会有相同的问题背景,从而需要应用相同的模式解决。 模式的概念最开始的时候出现在城市建筑领域中。后来,这个概念逐渐被计算机科学所 采纳,并在一本广为接受的经典书籍的推动下而流行起来。这本书就是DignPtens: EltfRbleObject-OritdSfte(设计模式:可复用面向对象软(e) 件元素),(r) (a) (s) 由4 位软(e) 件(m) 大(n) 师(so) 合写(e) 而(u) 成((a) (s) (e) 很多时候,直(e) 接(n) 用Go(o) F指(wa) 这(r) 4位作者,G(e) oF的意思是GangsofFour,即 四人帮)。 设计模式指的是在软件的建模和设计过程中运用到的模式。设计模式中的很多种方法其 实很早就出现了,并且应用得比较多。但是,直到GoF的书出来之前,并没有一种统一的认 识。或者说,那时并没有对模式形成一个概念,这些方法还仅处在经验阶段,并没有被系统地 整理,形成一种理论。 每个设计模式都系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设 计。这样,只要清楚这些设计模式,就可以完全或者很 大程度上吸收那些蕴含在模式中的宝贵经验,对面向 对象的系统能够有更完善的了解。更重要的是,这些 模式都可以直接用来指导面向对象系统中至关重要的 对象建模问题。如果有相同的问题背景,直接套用这 些模式就可以了,这可以省去很多工作量。图3-1 MVC 架构图 MVC模式就是一种很常见的设计模式。所谓的 MVC模式,即模型-视图-控制器(Model-View-Controler)模式。MVC架构图如图3-1所示。 1.Model端 在MVC中,模型是执行某些任务的代码,而这部分代码并没有任何逻辑决定用户端的表 示方法。Model只有纯粹的功能性接口,也就是一系列的公共方法,通过这些公共方法,便可 以取得模型端的所有功能。 2.View 端 在MVC模式里,一个Model可以有几个View端,而实际上多个View端是使用MVC 的原始动机。使用MVC模式可以允许存在多于一个的View端,并可以在需要的时候动态注 册所需要的View。 3.Controler端 MVC模式的视图端是与MVC的控制器结合使用的。当用户端与相应的视图发生交互 时,用户可以通过视窗更新模型的状态,而这种更新是通过控制器端进行的。控制器端通过调 用模型端的方法更改其状态值。与此同时,控制器端会通知所有注册了的视图刷新用户界面。 那么,使用MVC模式有哪些优点呢?MVC通过以下3种方式消除与用户接口和面向对 象的设计有关的绝大部分困难: (1)控制器通过一个状态机跟踪和处理面向操作的用户事件。这允许控制器在必要时创 建和破坏来自模型的对象,并且将面向操作的拓扑结构与面向对象的设计隔离开。这个隔离 有助于防止面向对象的设计走向歧途。 (2)MVC将用户接口与面向对象的模型分开。这允许同样的模型不用修改,就可使用许 多不同的界面显示方式。除此之外,如果模型更新由控制器完成,那么界面就可以跨应用再 使用 ( 。 3)MVC允许应用的用户接口进行大的变化,而不影响模型。每个用户接口的变化只需 Java高级框架应用开发与项目案例教程———Struts+Spring+Hibernate 要对控制器进行修改,但是控制器包含很少的实际行为,它是很容易修改的。 面向对象的设计人员在将一个可视化接口添加到一个面向对象的设计中时必须非常小 心,因为可视化接口的面向操作的拓扑结构可以大大增加设计的复杂性。 MVC设计允许一个开发者将一个好的面向对象的设计与用户接口隔离开,允许在同样 的模型中使用多个接口,并且允许在实现阶段对接口做大的修改,而不需要对相应的模型进行 修改。 3.2 MVC与Struts2的映射 Struts的体系结构实现了Model-View-Controler设计模式的概念,它将这些概念映射到 Web应用程序的组件和概念中。 1.控制器层(Controler) 与Struts1使用ActionServlet作为控制器不同,Struts2使用了filter技术, FilterDispatcher是Struts框架的核心控制器。该控制器负责拦截和过滤所有的用户请求。 如果用户请求以action结尾,该请求将被转入Struts框架进行处理。Struts框架获得 *.cion请求后, actocion类。例如, at将根据*.in请求的名称部分决定调用哪个业务控制at 对于tetato调用名为tscin处理该请求 。 s.cin请求, et的atoStus应用中的atotusxm在该文件中配置ato主要定 rtcin都被定义在srt.l文件中, cin时, 义了该action的name属性和clas 属性,其中name属性决定了该action处理哪个用户请求, 而clas 属性决定了action的实现类。例如,用于处理用户请求的acin实例,并没有与SevetAPI耦合, cnatoRgsto"torl 所以无法(.) 直接处理用户请求。为此,Struts框架提供了系列拦截器,该系列拦截器负责将 HtpServletRequest请求中的请求参数解析出来,传入Action中,并回调Action的execute() 方法处理用户请求。关于拦截器的概念,稍后会详细讲解。 2.显示层(View) Struts2框架改变了Struts1只能使用JSP作为视图技术的现状(当然,可以少量支持 Velocity等技术),它允许使用其他的视图技术(如FreMarker、Velocity等)作为显示层。 当Struts2的控制器调用业务逻辑组件处理完用户请求后,会返回一个字符串,该字符串 代表逻辑视图,它并未与任何视图技术关联。 当在strutsxml文件中配置action时,还要为action元素指定系列result子元素,每个 result子元素定义(.) 上述逻辑视图和物理视图之间的映射。一般情况下使用JSP技术作为视 图,故配置result子元素时没有type属性,默认使用JSP作为视图资源,如 。 ro>/pouteitrjp /product/regist_succ.jsp /product/register.jsp /index.html /product/products.jsp /product/products.jsp /product/products_showusers.jsp /product/products.jsp /product/products.jsp 第 3 章 Struts基础 37 /product/products_showusers.jsp /product/updateuser.jsp /product/updateuser.jsp < result name="changesuperuser_error">/product/changesuperuser.jsp /product/products.jsp /product/admin_orderuser.jsp < action name =" productIdCheckAction " class =" com. ascent. action. ProductIdCheckAction"> < action name =" * ProductManagerAction " class =" com. ascent. action. ProductManagerAction" method="{1}"> < param name="allowedTypes"> image/bmp,image/png,image/jpg,image/ gif,application/vnd.ms-excel 200000 /upload < result name="adminproductsshow">/product/admin_products_show.jsp /product/admin_products_show.jsp /product/upload_error.jsp /product/update_products_admin.jsp /product/products_show.jsp /product/products_search_show.jsp /product/userproducts_show.jsp /index.jsp /product/productdetail.jsp /product/cartshow.jsp /product/checkoutsucc.jsp /product/ordershow.jsp /product/admin_ordershow.jsp /product/orderitem_show.jsp /product/mailmanager_succ.jsp /product/mailmanager_fail.jsp /index.jsp 接下来具体看看struts.xml的主要内容。 1)包配置 Struts2框架中的核心组件是Action、拦截器等。Struts2框架使用包(package)管理 Action和拦截器等,package是多个Action、多个拦截器、多个拦截器引用的集合。 在struts.xml文件中,package元素用于定义包配置,每个package元素定义了一个包配 置。定义package元素时可以指定如表3-1所示的4个属性。 第 3 章 Struts基础 39 表3-1 package元素属性 属 性描 述 name 这是一个必填属性,它指定该包的名字,该名字是该包被其他包引用的key extends 该属性是一个可选属性,它指定该包继承其他包。继承其他包,可以继承其他包中的Action 定义、拦截器定义等 namespace 该属性是一个可选属性,它定义该包的命名空间 abstract 该属性是一个可选属性,它指定该包是否是一个抽象包。抽象包中不能包含Action定义 这里要特别了解命名空间的概念。考虑到在同一个Web应用中可能有同名的Action, Struts2以命名空间的方式管理Action。同一个命名空间里不能有同名的Action,不同的命 名空间里可以有同名的Action。Struts2 的命名空间的作用等同于Struts1里模块的作用, 它允许以模块化的方式组织Action。 Struts2不支持单独配置命名空间,而是通过为包指定namespace属性来为包里所有的 Action指定共同的命名空间。 看下面的配置文件代码。 /login.jsp /listUser.jsp 当某个包指定命名空间后,该包下所有的Action处理URL的应该是命名空间+Action 名。以上面名为ascentns的包为例,该包下包含了名为getUsers的Action,则该Action处理 的URL为 http://locahost:8080/ascentsdemo/ascentns/getUsers.action 如果某个包没有指定namespace属性,那么该包使用默认的命名空间,默认的命名空间总 是“”。默认命名空间里的Action可以处理任何模块下的Action请求。也就是说,如果存在 URL为/ascentns/test.action的请求,并且/ascentns的命名空间下没有名为test的Action, 则默认命名空间下名为test的Action也会处理用户请求。 除此之外,Struts2还可以指定根命名空间,即通过设置某个包的namespace=“/”指定根 命名空间。如果请求为/test.action,系统会在根命名空间(“/”)中查找名为test的action,如 果在根命名空间中找到了名为test的action,则由该action处理用户请求。否则,系统将转入 默认命名空间中查找名为test的action,如果默认的命名空间里有名为test的action,则由该 action处理用户请求;如果两个命名空间里都找不到名为test的Action,则系统出现错误。 2)Action配置 struts.xml中最重要的是关于Action的配置。Action是Struts2的基本“程序单位”。 (1)基本配置。 配置Action时,需要指定该Action的实现类,并定义Action处理结果与视图资源之间的 映射关系。 Java高级框架应用开发与项目案例教程———Struts+Spring+Hibernate 40 下面是struts.xml配置文件的示例: /index.html /product/products.jsp /product/products.jsp /product/products_showusers.jsp /product/products.jsp /product/products.jsp 前面提到,Struts2使用包组织Action,因此,Action定义是放在包定义下完成的,定义 Action通过使用package下的Action子元素完成。定义Action时,至少需要指定它的name 属性,该name属性既是该Action的名字,也是它需要处理的URL的一部分。 注意:Struts2的Action名字就是它所处理的URL 的前半部分。与Struts1不同, Struts1的Action配置中的name属性指定的是该Action关联的ActionForm,而path属性 才是该Action处理的URL。Struts2去除了这些易混淆的地方,Action的name属性等同于 Struts1中Action的path属性。 除此之外,通常还需要为Action元素指定一个class属性,它指定了该Action的实现类, 如。 前面提到过,Action只是一个业务控制器,它在处理完用户请求后,需要将指定的视图资 源呈现给用户。因此,配置Action时,应该配置逻辑视图和物理视图资源之间的映射。这是 通过元素定义的,每个元素定义逻辑视图和物理视图之间的一次 映射。关于result的配置,后面有更详细的讲解。 另外,还可以为action 元素指定method属性。Struts框架允许一个表单元素里包含多 个按钮,分别提交给不同的处理逻辑。Struts2提供了一种处理方法,即将一个Action处理类 定义成多个逻辑Action。如果在配置元素时指定action的method属性,则可 以让Action类调用指定方法,而不是用execute()方法处理用户请求。 上面定义了login和regist两个逻辑Action,它们对应的物理处理类都是com.ascenttech. action.LoginAction。login和regist两个Action虽然有相同的处理类,但处理逻辑不同,它通 过method()方法指定,其中名为regist的Action对应的处理逻辑为默认的exeute()方法,而 名为login的Action对应的逻辑为指定的login()方法。 再次看上面struts.xml文件中两个元素的定义,发现两个action定义的绝 第 3 章 Struts基础 41 大部分相同,因此这种定义有大量冗余。为了解决这个问题,Struts2还有另一种形式的动态 方法调用,即使用通配符的方式。 (2)使用通配符。 在配置元素时,可以指定name、class和method属性,这3个属性都可支持 通配符,这种使用通配符的方式是动态方法调用的一种形式。当使用通配符定义Action的 name属性时,相当于一个action元素定义多个逻辑Action。 以下举例说明: 解释上面代码的含义:上面定义的不是一个普通的action,而是定义了一系列的action, 只要URL是*Action.action的模式,都可以通过该Action进行处理,但该Action定义了一 个表达式{1},该表达式的值就是name属性值中的第一个*的值。 例如,如果用户请求的URL是loginAction.action,则调用该action的login()方法;如果 用户请求的URL是registAction.action,则调用该action的regist()方法。LoginAction类不 再包含默认的execute()方法,而是包含了regist()和login()两个方法,这两个方法与execute()方 法除了方法名不同外,其他完全相同。 除此之外,表达式也可出现在元素的class属性中,即Struts2允许将一系 列Action类配置成一个元素。例如: …< /action> 上面的定义片段定义了一系列的Action,这些Action名字应该匹配* Action模式,没有指定method属性,所以总是使用execute()方法处理用户请求。但class属 性值使用了表达式,上面配置片段的含义是,如果有URL 为RegistAction.action请求,将匹 配*Action模式,而交给该Action处理,其第一个*的值为Regist,该Regist传入class属性 值,即该Action的处理类为com.ascent.action.RegistAction。 如果需要,Struts2允许在class属性和method属性中同时使用表达式。看如下的配置 片段: 当一个action为Product_update.action的时候,将调用ProductAction的update()方法 处理用户请求。现在的问题是,当用户请求的URL 同时匹配多个Action时,究竟由哪个 Action处理用户请求? 如果有URL为abcAction.action的请求,struts.xml文件有名为abcAction的Action,则 一定由该Action处理用户请求;如果struts.xml文件没有名为abcAction的Action,则搜索 name属性值匹配abcAction的Action,例如name为*Action或*,*Action并不会比*更 优先匹配abcAction的请求,而是先找到哪个Action,就先由哪个Action处理用户的请求。 因此,应该将名为*的Action配置在最后,否则Struts2将使用该Action处理所有希望使用 Java高级框架应用开发与项目案例教程———Struts+Spring+Hibernate 42 模式匹配的请求。 在AscentWeb项目的struts.xml中,使用了通配符: < action name="*CartManagerAction" class="com.ascent.action.CartManagerAction" method="{1}"> /product/cartshow.jsp /product/checkoutsucc.jsp /product/ordershow.jsp /product/admin_ordershow.jsp /product/orderitem_show.jsp (3)处理结果。 前面已经提到,Action仅负责处理用户请求,它只是一个控制器,不能也不应该直接提供 对浏览者的响应。当Action处理完用户请求后,处理结果应该通过视图资源实现,而控制器 应该控制将哪个视图资源呈现给浏览者。 Action处理完用户请求后,将返回一个普通字符串,整个普通字符串就是一个逻辑视图 名。struts.xml中包含逻辑视图名和物理视图之间的映射关系,一旦收到Action返回的某个 逻辑视图名,系统就会把对应的物理视图呈现给浏览者。 相对于Struts1框架而言,Struts2的逻辑视图不再是ActionForward对象,而是一个普 通字符串,这样的设计更有利于将Action类与Struts2框架分离,提供了更好的代码复 用性。 除此之外,Struts2还支持多种结果映射,实际资源不仅可以是JSP视图资源,也可以是 FreeMaker或Velocity等视图资源,甚至可以将请求转给下一个Action处理,形成Action的 链式处理。 ① 处理结果配置。 Struts2通过在Struts.xml文件中使用元素配置结果。根据 元素所在位置的不同,Struts2提供了两种结果。 . 局部结果:将作为元素的子元素配置。 . 全局结果:将作为元素的子元素配置。 先介绍局部结果,它的作用范围是对特定的某个Action 有效。局部结果是通过在 元素中指定 元素配置的,一个 元素可以有多个 元素,这表示一个action可以对应多个结果。 最典型的配置片段如下: /index.html /product/products.jsp 第 3 章 Struts基础 43 /product/products.jsp /product/products_showusers.jsp /product/products.jsp /product/products.jsp 注:还可以使用子元素配置结果,其中元素的name属性可 以为如下两个值。 .location:该参数指定了该逻辑视图对应的实际视图资源。 . parse:该参数指定是否允许在实际视图名字中使用OGNL表达式,该参数值默认为 true。如果设置该参数值为false,则不允许在实际视图名中使用表达式。通常无须修 改该属性值。 下面了解一下全局结果。Struts2的元素配置,也可放在 元素中配置,当在元素中配置元素时,该元素配 置了一个全局结果,全局结果的作用范围对所有的Action都有效。 如果一个Action里包含了与全局结果里同名的结果,则Action里的局部Action会覆盖 全局Action。也就是说,当Action处理用户请求结束后,会首先在本Action里的局部结果里 搜索逻辑视图对应的结果,只有在Action里的局部结果里找不到逻辑视图对应的结果,才会 到全局结果里搜索。 ② Struts2支持的处理结果类型。 Struts2支持使用多种视图技术,如JSP、Velocity和FreeMarker等。当一个Action处 理用户请求结束后,仅返回一个字符串,这个字符串就是逻辑视图名,但该逻辑视图并未与任 何的视图技术及任何的视图资源关联。实际上,结果类型决定了Action处理结束后,下一步 将执行哪种类型的动作。 Struts2的结果类型要求实现com.opensymphony.xwork.Result,这个结果是所有Action 执行结果的通用接口。如果需要自己的结果类型,应该提供一个实现该接口的类,并且在 struts.xml文件中配置该结果类型。 Struts2的Struts-default.xml和各个插件中的Struts-plugin.xml文件中提供了一系列 的结果类型,表3-2列出的就是Struts2支持的结果类型。 表3-2 Struts2支持的结果类型 结果类型描 述 Chain结果类型Action链式处理的结果类型 Chart结果类型用于整合JFreeChart的结果类型 dispatcher结果类型用于JSP整合的结果类型 freemarker结果类型用于freemarker整合的结果类型 httpheader结果类型用于控制特殊的HTTP行为的结果类型 Jasper结果类型用于JasperReports整合的结果类型 Jsf结果类型用于与JSF整合的结果类型 redirect结果类型用于直接重定向到其他URL的结果类型 续表 Java高级框架应用开发与项目案例教程———Struts+Spring+Hibernate 44 结果类型描 述 redirect-action结果类型用于直接重定向到Action的结果类型 Stream 结果类型用于向浏览器返回一个InputStream(一般用于文件下载) Tiles结果类型用于与Tiles整合的结果类型 Velocity结果类型用于与Velocity整合的结果类型 XSLT结果类型用于与XML/XSLT整合的结果类型 plaintext结果类型用于显示某个页面的源代码的结果类型 上面一共列出14种类型,其中dispatcher结果类型是默认的类型,也就是说,如果省略了 type属性,默认type 属性为dispatcher,它主要用于与JSP 页面整合。下面重点介绍 plaintext、redirect和redirect-action3种结果类型。 a.plaintext结果类型 这个结果类型并不常用,因为它的作用太过局限:它主要用于显示实际视图资源的源代 码。在struts.xml文件中采用如下的配置片段: /welcome.jsp gb2312 这里使用了plaintext结果类型,系统将把视图资源的源代码呈现给用户。如果在 welcome.jsp页面的代码中包含了中文字符,使用plaintext结果将会看到乱码。为了解决这 个问题,Struts2通过gb2312元素设置使用特定的编 码解析页面代码。 b.redirect结果类型 这种结果类型与dispatcher结果类型相对,dispatcher结果类型是将请求forward(转发) 到指定的jsp资源;而redirect结果类型则意味着将请求redirect(重定向)到指定的视图资源。 dispatcher结果类型与redirect结果类型的差别主要是转发和重定向的差别;重定向的 效果是重新产生一个请求,因此所有的请求参数、请求属性、Action实例和Action中封装的属 性全部丢失。 完整地配置一个redirect的Result,可以指定如下两个参数: .location:该参数指定Action处理完用户请求后跳转的地址。 . parse:该参数指定是否允许在location参数值中使用表达式,该参数默认为true。 c.redirect-action结果类型 当一个Action处理结束后,直接将请求重定向(是重定向,不是转发)到另一个Action 时,应该使用redirect-action结果类型。配置redirect-action结果类型时,可以指定如下两个 参数:. actionName:该参数指定重定向的Action名。 . namespace:该参数指定需要重定向的Action所在的命名空间。 第 3 章 Struts基础 45 下面是一个使用redirect-action结果类型的配置实例: /ss login ③ 动态结果。 动态结果的意思是在指定实际视图资源时使用了表达式语法,通过这种语法可以允许 Action处理完用户请求后,动态转入实际的视图资源。 实际上,Struts2不仅允许在class属性、name属性中使用表达式,还可以在元 素的子元素中使用表达式。下面提供了一个通用Action,该Action可以配置成 如下形式: /{1}.jsp 在上面的Action定义中,Action的名字是一个*,即它可以匹配任意的Action,即所有的 用户请求都可通过该Action处理。因为没有为该Action指定class属性,即该Action使用 ActionSupport作为处理类,而且因为该ActionSupport类的execute()方法返回success的字 符串,即该Action总是直接返回result中指定的JSP资源,JSP资源使用表达式生成资源名。 上面Action定义的含义是:如果请求a.action,则进入a.jsp;如果请求b.action,则进入b.jsp 页面……以此类推。 另外,在配置元素时,还允许使用OGNL表达式,这种用法允许让请求参数 决定结果。在配置元素时,不仅可以使用${0}表达式形式指定视图资源,还可 以使用${属性名}的方式指定视图资源。在后面这种配置方式下,${属性名}里的属性名就 是对应Action实例里的属性。例如: edit.action? productName=${myProduct.name} 对于上面的表达式语法,要求action中必须包含myProduct属性,并且myProduct属性 必须包含name属性,否则${myProduct.name}表达式的值为null。 3)include(包含)配置 在大部分应用里,随着应用规模的增加,系统中的Action数量也会大量增加,导致struts. xml配置文件变得非常臃肿。为了避免这种情况,可以将一个struts.xml配置文件分解成多 个配置文件,然后在struts.xml文件中包含其他配置文件。通过这种方式,Struts2提供了一 种模块化的方式管理struts.xml配置文件,体现了软件工程中“分而治之”的原则。 Struts2默认只加载WEB-INF/class下的struts.xml文件,所以必须通过struts.xml文 件包含其他配置文件。 在struts.xml文件中包含其他配置文件通过元素完成,配置元 素需要指定一个必需的属性,该属性指定了被包含配置文件的文件名。被包含的struts配置 文件也是标准的Struts2配置文件,一样包含DTD信息、Struts2配置文件的根元素等信息。 Java高级框架应用开发与项目案例教程———Struts+Spring+Hibernate 通常,将Strts2的所有配置文件都放在Web应用的WEBINF/lses路径下,tutxm u-casrs.l 文件包含了其他的配置文件,Srttutxml文件,从而完成加载所有配置 tus2框架自动加载srs. 信息 4 。 )Bean配 置 Struts2框架是一个可扩展性的框架。对于框架的大部分核心组件,Struts2并不是直接 以硬编码的方式写在代码中,而是以自己的IoC(控制反转)容器管理框架的核心组件。关于 IoC,第10章将会详细讲解。 Struts2框架以可配置的方式管理Struts的核心组件,从而允许开发者可以很方便地扩 展该框架的核心组件。当开发者需要扩展,或者替换Struts2的核心组件时,只提供自己的组 件实现类,并将该组件实现类部署在Struts2的IoC容器中即可。 通常使用元素在sr.l文件中定义Bn。ben元素属性见表3-3。 eatutsxmeaa 表3- 3 bean元素属性 描述 这个属性是一个必填属性,它指定了Bean实例的实现类 这个属性是一个可选属性,它指定了Bean实例实现的Struts2规范,该规范通常是通过某个 Type 接口实现的,因此该属性的值通常是一个Struts2接口。如果需要将Bean实例作为Struts2 组件使用,则应该指定该属性值 该属性指定了Bean实例的名字,对于有相同type类型的多个Bean,它们的name属性不能 相同。这个属性也是一个可选属性 该属性指定Bean实例的作用域。该属性是一个可选属性,属性值只能是default、singleton、 request、sesion或thread中之一 该属性指定Bean是否使用静态方法注入。通常,当指定了type属性时,该属性不应该指定 为true 该属性指定该Bean是否为一个可选的Bean,该属性是一个可选属性 属性 clas Name Scope Static optional 在strt.l文件中定义Ben时,通常有如下两个作用: usxma .创建该Bean的实例,将该实例作为Struts2框架的核心组件使用。 .Bean包含的静态方法需要一个值注入。 在第一种用法下,因为Bean实例往往是作为一个核心组件使用的,因此需要告诉Struts 容器该实例的作用———就是该实例实现了哪个接口,这个接口往往定义了该组件必须遵守的 规范。 第二种用法则可以很方便地允许不创建某个类的实例,却可以接受框架常量。在这种用 法下,通常需要设置static="true"。 注意:对于绝大部分Struts2应用而言,无须重新定义Struts2框架的核心组件,也就无 须在strutsxml文件中定义Bean。 5)常量配置(.) 在strt.l文件中配置常量是一种指定Stus2属性的方式。稍后会介绍如何在 usxmrtstuspoetes文件中配置Srts2属性,这两种方式的作用基本相似。通常推荐在srt. rt.rpritutusxml文件中定义Struts2属性,而不是在strutsproperties文件中定义Struts2属性的方式, 这主要是为了保持与WebWork的向后兼容性。另(.) 外,还可以在wexml文件中配置Srt b.tus2 第 3 章 Struts基础 47 常量。通 常,Struts2框架按如下搜索顺序加载Struts2常量: .struts-default.xml:该文件保存在struts2-2.0.6.jar文件中。 .struts-plugin.xml:该文件保存在struts2-xxx-2.0.6.jar等Struts2插件jar文件中。 .struts.xml:该文件是Web应用默认的Struts2配置文件。 .struts.properties:该文件是Web应用默认的Struts2配置文件。 . web.xml:该文件是Web应用的配置文件。 上面指定了Struts2 框架搜索Struts2 常量顺序,如果在多个文件中配置了同一个 Struts2常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值。 在不同的文件中配置常量的方式不一样,但不管在哪个文件中,配置Struts2常量都需要 指定两个属性:常量name和常量value。 其中,在struts.xml文件中通过元素constant配置常量。配置常量需要指定两个必填的 属性。. name:该属性指定了常量name。 . value:该属性指定了常量value。 如果需要指定Struts2的国际化资源文件的baseName为mess,则可以在strust.xml文 件中使用如下的代码片段: image/bmp,image/png,image/jpg,image/gif, application/vnd.ms-excel 200000 第 3 章 Struts基础 49 2.struts.properties配置文件 除struts.xml核心文件外,Struts2框架还包含一个struts.properties文件,该文件通常 放在Web应用的WEB-INF/classes路径下。它定义了Struts2框架的大量属性,开发者可以 通过改变这些属性满足个性化应用的需求。 struts.properties中定义的Struts2属性见表3-4。 表3-4 struts.properties中定义的Struts2属性 属 性描 述 struts.configuration 该属性指定加载Struts2配置文件的配置文件管理器。该属性的默 认值是org.apache.Struts2.config.DdfaultConfiguration,这是Struts 2默认的配置文件管理器。如果需要实现自己的配置管理器,开发 者开发一个实现configuration接口的类,该类可以自己加载Struts 2配置文件 Struts.locale 指定Web应用的默认Locale Struts.i18n.encoding 指定Web应用的默认编码集。该属性对于处理中文请求参数非常 有用,对于获取中文请求参数值,应该将该属性值设置为GBK 或 者GB2312。 提示:当设置该参数为GBK 时,相当于调用httpservletrequest的 setcharacterencoding()方法 struts.objectFactory 指定Struts2默认的objectFactorybean,该属性的默认值是Spring struts.objectFactory.spring.autoWire 指定Spring框架的自动装配模式,该属性的默认值是name,即默认 根据Bean的name属性自动装配 struts.objectFactory.spring.useClassCache 该属性指定整合Spring框架时,是否缓存Bean实例。该属性只允 许使用true和false两个属性值,它的默认值是true。通常不建议 修改该属性值 struts.objectTypeDeterminer 该属性指定Struts2的类型检测机制,通常支持tiger和notiger两 个属性值 Struts.multipart.parser 该属性指定处理multipart/form-data的MIME类型(文件上传)请 求的框架。该属性支持cos、pell和jakarta等属性值,即分别对应使 用cos的文件上传框架、pell上传及common-fileupload文件上传框 架。该属性的默认值为jakarta。 如果需要使用cos或者pell的文件上传方式,则应将对应的JAR文 件复制到Web应用中。例如,使用cos上传方式,则需要自己下载 cos框架的JAR文件,并将该文件放在WEB-INF/lib路径下 Struts.multipart.savedir 该属性指定上传文件的临时保存路径,默认值是javax.servlet. context.tempdir Struts.multipart.maxsize 该属性指定Struts2文件中整个请求内容允许的最大字节数 Sturts.custom.properties 该属性指定Struts2应用加载用户自定义的属性文件,该自定义属 性文件指定的属性不会覆盖struts.properties文件中指定的属性。 如果需要加载多个自定义属性文件,则多个自定义属性文件的文件 名以英文逗号(,)隔开 Java高级框架应用开发与项目案例教程———Struts+Spring+Hibernate 续表 属性 Stusmae.ls rt.pprca Stusatoetnin rt.cin.xeso Stussresai rt.ev.ttc Stus.srvesaic.rsrcahe rte.ttbowec Stuseal.niehdnoain rt.nbedyamcmtoivcto Stuseal.lseiatons rt.nbesahsnciname Stustg.lsna rt.aatytx Stusdvmoe rt.ed Stusin.eod rt.18rla Stusu.h rt.iteme Stusu.empaer rt.itltDi Stusu.empaeux rt.itltSfi Stuscniuain.lrla rt.ofgrtoxm.eod Stusvlcty.cnifil rt.eoiofge Stusvlcttobxoain rt.eoiy.ololcto Stusvlcttobxoain rt.eoiy.ololctoStusulhpot rt.r. tp.r 描述 指定将HTTP请求映射到指定Action的映射器,Struts2提供了默认 的映射器or.cesrt2.iace.ardfutcinmaer。默 gpah.tusdspthrmppe.ealatopp认映射器根据请求的前缀与Action的name属性完成映射 该属性指定需要Struts2处理的请求后缀,默认值是action,即所有 匹配*.tin的请求都由Stts2处理。如果用户需要指定多个请 求后缀,(a) 则(c) 多(o) 个后缀之间以英文(r) 逗号(,)(u) 隔开 该属性设置是否通过JAR文件提供静态内容服务,该属性只支持 te和fle属性值,该属性的默认属性值是t该(r) 属(u) 性设置(a) 浏览器是否缓存静态内容。当应用(r) 处(u) 于开发阶段时,(e) (s) 若 希望每次请求都获得服务器的最新响应,则可设置该属性为false 该属性设置Stts2是否支持动态方法调用,默认值是true。如果需要关闭动态方(r) 法(u) 调用,则可设置该属性为false 该属性设置Struts2是否允许在Atin名中使用斜线,默认值是 false。如果开发者希望允许在Action(c) 名(o) 中使用斜线,则可设置该属 性为true 该属性指定是否允许在Stts2标签中使用表达式语法,因为通常需要在标签中使用表达式语(r) 法,(u) 故此属性应设置为true。该属性的 默认值是true 该属性用于设置Struts2应用是否使用开发模式。如果设置该属性 为true,则可以在应用出错时显示更多、更友好的出错提示。该属性 只接受true和false两个值,默认值是fle。通常,应用在开发阶段, 将该属性设置为true,当进入产品发布阶段(a) 后,(s) 则该属性设置为false 该属性用于设置是否每次HTTP请求到达时,系统都重新加载资源 文件,默认值是false。在开发阶段将该属性设置为true会更有利于 开发,但在产品发布阶段应将该属性设置为false。 提示:在开发阶段将该属性设置为tue,可以在每次请求时重新加 载国际化资源文件,从而让开发者看到(r) 实时开发效果;在产品发布 阶段将该属性设置为false,是为了提供响应性能,每次请求都重新 加载资源文件会大大降低应用的性能 该属性指定视图标签默认的视图主题,默认值是xhtml 该属性指定视图主题所需要模板文件的位置,默认值是template,即 默认加载template路径下的模板文件 该属性指定模板文件的后缀,默认值是ftl。该属性还允许使用ftl、 vm或jsp,分别对应FreMarker、Velocity和JSP模板 该属性设置当strt.l文件改变后,系统是否自动重新加载该文 usxm 件,默认值是false 该属性指定Veloiy框架所需的veoiy.rpris文件的位置,默 ctlctpoete 认值是velctpoete oiy.rpris 该属性指定Velocity框架的Ctt位置,如果该框架有多个 Context,则多个Context之间以英文(o) 逗(e) 号(,)(x) 隔开 该属性指定Velocity框架的toolbox的位置 该属性指定Web应用所在的监听端口。该属性通常没有太大的用 户,只是当Struts2需要生成URL时(如Url标签),该属性才提供 Web应用的默认端口 第3章 Struts基础 续表 属性 rt.r. tpot Stusulhs.pr Stusulicueaams rt.r.nldpr Stuscsom.18rsucs rt.utin.eore Stusdspthrpaamtrraon rt.iace.reesWokrud rtrre.nge. sn Stus.femakrmaarclaame StusfemakrwappratMap rt.rre.re.l Stusxl.oah rt.stncce Stus.cnfiuaion.ie rtogrtfls 描述 该属性类似于Strt.r. tp.rt属性的作用,区别是该属性指定 usulhpo 的是Web应用的加密服务端口 该属性指定Stts2生成URL时是否包含请求参数。该属性接受 none、get和al3(r) 个属性值,(u) 分别对应于不包含、仅包含GET类型请 求参数和包含全部请求参数 该属性指定Struts2应用所需要的国际化资源文件,如果有多份国 际化资源文件,则多个资源文件的文件名以英文逗号(,)隔开 某些JavaEE服务器不支持HtpServletRequest调用getparameterMap() 方法,此时可以设置该属性值为true解决该问题。该属性的默认值 是false。对于WebLogic、Orion和OC4J服务器,通常应该设置该 属性为true 该属性指定Struts2使用的FreMarker管理器,默认值是org. apah.tusvesfemakrFemakrMaager,这是Stus2 cesrt2.iw.rre.rrenrt 内建的FreMarker管理器 该属性只支持true和false两个属性值,默认值是true。通常无须 修改该属性值 该属性指定XSLTResult是否使用样式表缓存。当应用处于开发 阶段时,该属性通常设置为true;当应用处于产品使用阶段时,该属 性通常设置为false 该属性用于指定Stts2框架默认加载的配置文件,如果需要指定默认加载多个配置文(r) 件,(u) 则多个配置文件的文件名之间以英文逗号 (,)隔开。该属性的默认值为Strt-eal.l,srt-pugn.l, usdfutxmtuslixmstusxml,看到该属性值,读者应该明白为什么Srts2框架默认 rt.tu 加载strt.l文件 usxm 有时开发者不喜欢使用额外的stuspoeteSrttus rt.rpris文件。前面提到,tus2允许在srt. xml文件中管理Stus2属性,在stusl文件中管理Stus2属性,在stusxml文件中 rtrtxmrtrt. 通过配置contnt元素,一样可以配置这些(.) 属性。前面已经提到,建议尽量在srs.l文件 satutxm 中配置Struts2常量 。 3.4 创建Controler组件 Struts的核心是Controler组件。它是连接Model和View组件的桥梁,也是理解Struts 架构的关键。正如前面提到的,Struts2的控制器由两个部分组成:FilterDispatcher和业务 控制器Action。 3.1 FleDipthr 4.itrsace 任何MVC框架都需要与Web应用整合,这就离不开web.l文件,只有配置在we xmb. xml文件中,Filter/servlet才会被应用加载。对于Struts2框架而言,需要加载 FilterDispatcher。因为Struts2将核心控制器设计成filter,而不是一个servlet,故为了让 Web应用加载Filtrsacer,需要在wexml文件中配置Fitrsacer。 eDipthb.leDipth