全方位解析:Struts2配置文件

1.1.1 web.xml配置

任何MVC框架都须要与Web应用整合,就不得不依赖于web.xml文件,只有配置在web.xml文件中的Servlet、Filter才会被应用加载。web

1. 核心控制器及参数配置编程

全部MVC框架都须要Web应用加载一个核心控制器,对于Struts2框架而言,其须要加载FilterDispatcher,只要Web应用负责加载FilterDispatcher,FilterDispatcher将会加载应用的Struts2框架。安全

FilterDispatcher实质是一个过滤器,它负责初始化整个Struts2框架而且处理全部的请求。这个过滤器能够包括一些初始化参数,有的参数指定了要加载哪些额外的xml配置文件,还有的会影响Struts2框架的行为。除了FilterDispatcher外,Struts2还提供了一个ActionContexCleanUp过滤器,它的主要任务是当有其它一些过滤器要访问一个初始化好了的Struts2框架的时候,负责处理一些特殊的清除任务。ActionContexCleanUp过滤器主要配合其余插件过滤器使用。详细配置,以下图所示:服务器

clip_image002

clip_image004

其中有3个初始化参数有特殊意义: session

config:该参数的值是一个以英文逗号(,)隔开的字符串,每一个字符串都是一个XML配置文件的位置。Struts 2框架将自动加载该属性指定的系列配置文件。 多线程

actionPackages:该参数的值也是一个以英文逗号(,)隔开的字符串,每一个字符串都是一个包空间,Struts 2框架将扫描这些包空间下的Action类。 app

configProviders:若是用户须要实现本身的ConfigurationProvider类,用户能够提供一个或多个实现了ConfigurationProvider接口的类,而后将这些类的类名设置成该属性的值,多个类名之间以英文逗号(,)隔开。框架

loggerFactory:指定LoggerFactory实现类的类名。jsp

除此以外,还可在此处配置Struts 2常量,每一个<init-param>元素配置一个Struts2常量,其中<param-name>子元素指定了常量name,而<param-value>子元素指定了常量value。ide

至于filter-mapping属性是过滤器(Filter)必须的一个属性,用于过滤请求的路径,此处通常就设为/*形式,对全部请求uri进行拦截(过滤),除非你要作一些特殊的处理。

2. 标签库配置

若是web容器是J2EE1.3(servlet2.3)及之前的规范,因为不会自动加载Struts2的标签库,因此须要在web.xml文件中手动加载Struts2的标签库,将struts-tags.tld文件,通常复制放在WEB-INF下面,能够本身指定,在web.xml中配置的加载标签订义文件以下:

clip_image006

但若是web容器是J2EE1.4(servlet2.4),那么web容器会自动加载标签库,Struts 2的标签库定义文件包含在struts2-core-2.1.6.jar文件里,在struts2-core-2.1.6.jar文件的META-INF路径下,包含了一个struts-tag.tld文件, 这个文件就是Struts 2的标签库定义文件,Servlet 2.4规范会自动加载该标签库文件,避免了在web.xml文件中从新定义Struts2标签库文件的URI。其中struts-tags.tld文件里包含了加载信息的片段,以下:

clip_image008

1.1.2 struts.properties配置

struts.properties文件定义了Struts 2框架的大量属性(也称为Struts2常量),开发者能够经过改变这些属性来知足应用的需求。

struts.properties文件是一个标准的Properties文件,该文件包含了系列的key-value对象,每一个key就是一个Struts 2属性,该key对应的value就是一个Struts2属性值。

struts.properties文件一般放在Web应用的WEB-INF/classes路径下。实际上,只

要将该文件放在Web应用的CLASSPATH路径下,Struts 2框架就能够加载该文件。

其实,配置Struts2常量有3个地方:

a) 在struts.properties文件中配置常量;

b) 在web.xml文件中配置FilterDispatcher指定初始化参数来配置常量;

c) 在struts.xml文件中使用<constant …/>元素来配置常量;

下面将该文件必须知道的配置参数详细列举出来,以下图所示:

clip_image010

clip_image012

其余详细配置参数,请参考:http://www.javashuo.com/tag/struts.properties

1.1.3 struts.xml配置

struts.xml文件主要负责管理应用中的业务控制器Action映射,以及该Action包含的Result定义等。在默认状况下,Struts2框架将自动加载放在WEB-INF/classes路径下的struts.xml文件。

另外,struts-default.xml文件是Struts2框架的默认配置文件,Struts2框架每次都会自动加载该文件。

不只如此,Struts2框架提供了一种相似Eclipse的扩展方式,容许以一种“可插拔”的方式来安装插件。如:Spring插件、JSF插件等,它们都提供了一个相似的struts2-xxx-plugin.jar的文件,只要将该文件放在WEB-INF/lib路径下,Struts2框架会自动加载该插件。在struts2-xxx-plugin.jar文件中,包含struts-plugin.xml文件,Struts2框架同时也会加载该文件。经过这种方式,Struts2框架容许使用可插拔的方式管理Struts2框架。

上面介绍的struts.xml、struts-default.xml、struts-plugin.xml,所配置的内容没有任何区别,只是加载时顺序有前后(struts-default.xml、struts-plugin.xml、struts.xml),若三个文件中存在相同的配置,后加载的配置会覆盖先加载的配置。

1.struts.xml文件结构

<!-- struts是Struts 2配置文件的根元素 -->

<struts>

<!-- 常量配置元素能够出现零次,也能够出现无数次 -->

<constant name="" value="" />

<!-- Bean配置元素能够出现零次,也能够出现无数次 -->

<bean type="" name="" class="" scope="" static="" optional="" />

<!-- 配置文件包含元素能够出现零次,也能够出现无数次 -->

<include file="" />

<!-- 包元素是Struts配置文件的核心,该元素能够出现零次,或者无数次 -->

<package name="必填的包名" extends="" namespace="" abstract="" externalReferenceResolver>

<!-- 返回结果类型集合元素能够出现,也能够不出现,最多出现一次 -->

<result-types>

<!-- 返回结果类型元素必须出现,能够出现无数次 -->

<result-type name="" class="" default="true|false">

<!-- 返回结果类型参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</result-type>

</result-types>

<!-- 拦截器集合元素能够出现,也能够不出现,最多出现一次 -->

<interceptors>

<!-- 拦截器集合元素的interceptor元素和interceptor-stack至少出现其中之一, 也能够两者都出现 -->

<!-- 拦截器元素能够出现零次,也能够无数次 -->

<interceptor name="" class="">

<!-- 拦截器参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</interceptor>

<!-- 拦截器栈元素能够出现零次,也能够无数次 -->

<interceptor-stack name="">

<!-- 引用拦截器元素必须出现,能够出现无数次 -->

<interceptor-ref name="">

<!-- 引用拦截器参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</interceptor-ref>

</interceptor-stack>

</interceptors>

<!-- 默认拦截器(栈)引用元素能够出现零次,也能够无数次 -->

<default-interceptor-ref name="">

<!-- 默认拦截器(栈)引用参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>

</default-interceptor-ref>

<!-- 默认Action引用元素能够出现零次,也能够无数次 -->

<default-action-ref name="">

<!-- 默认Action引用参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</default-action-ref>?

<!-- 全局返回结果集合元素能够出现零次,也能够无数次 -->

<global-results>

<!-- 返回结果元素必须出现,能够出现无数次 -->

<result name="" type="">

<!-- 该字符串内容能够出现零次或屡次 -->

映射资源

<!-- 返回结果参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</result>

</global-results>

<!-- 全局异常映射集合元素能够出现零次,也能够无数次 -->

<global-exception-mappings>

<!-- 异常映射元素必须出现,能够出现无数次 -->

<exception-mapping name="" exception="" result="">

异常处理资源

<!-- 异常映射参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</exception-mapping>

</global-exception-mappings>

<!-- Action元素能够出现零次,也能够无数次 -->

<action name="" class="" method="" converter="">

<!-- Action参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

<!-- 返回结果元素能够出现零次,也能够无数次 -->

<result name="" type="">

映射资源

<!-- 结果参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</result>

<!-- 拦截器(栈)引用元素能够出现零次,也能够无数次 -->

<interceptor-ref name="">

<!-- 拦截器(栈)引用参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</interceptor-ref>

<!-- 异常映射元素能够出现零次,也能够无数次 -->

<exception-mapping name="" exception="" result="">

异常处理资源

<!—异常映射参数元素能够出现零次,也能够无数次 -->

<param name="参数名">参数值</param>*

</exception-mapping>

</action>

</package>*

<!-- 未知处理器栈元素可出现零次或1次 -->

<unknown-handler-stack>

<!-- 未知处理器元素可出现零次或屡次 -->

<unknown-handler-ref name=" ">...</unknown-handler-ref>*

</unknown-handler-stack>?

<struts>

2.struts.xml标签使用介绍

a) 使用<include>标签重用配置文件

在Struts2中提供了一个默认的struts.xml文件,但若是package、action、

interceptors等配置比较多时,都放到一个struts.xml文件不太容易维护。所以,就须要将struts.xml文件分红多个配置文件,而后在struts.xml文件中使用<include>标签引用这些配置文件。这样作优势以下:

1) 结构更清晰,更容易维护配置信息;

2) 配置文件能够复用。若是在多个Web程序中都使用相似或相同的配置文件,那么可使用<include>标签来引用这些配置文件,这样能够减小工做量。

clip_image014

小提示:

用<include>引用的xml文件也必须是完整的struts2配置,如:必须包括头部信息等。实际上<include>在引用时是单独解析的xml文件,而不是将被引用的文件插入到struts.xml文件中。

一般,将Struts2的全部配置文件都放在Web应用的WEB-INF/classes路径下,struts.xml文件包含了其余的配置文件,Struts2框架自动加载struts.xml文件时,完成加载全部配置信息。

b) 使用<constant>标签进行常量配置

在以前提到struts.properties配置文件的介绍中,咱们曾经提到全部在struts.properties文件中定义的属性,均可以配置在struts.xml文件中。而在struts.xml中,是经过<constant>标签来进行配置的。

clip_image016

小提示:

一般推荐在struts.xml文件中配置Struts2常量,而不是在struts.properties文件中配置常量。之因此保留使用struts.properties文件配置Struts2常量的方式,主要是为了保持与WebWork之间的兼容性。

统一块儿来看,Struts2的常量配置能够在struts-plugin.xml、struts.xml、struts.properties、web.xml中配置,则Struts2框架会按以下搜索顺序加载Struts2常量:default.properties、struts-default.xml、struts-plugin.xml、struts.xml、struts.properties、web.xml,若是在多个文件中配置了同一个Struts2常量,则后面文件中配置的常量值会覆盖前面文件中配置的常量值。

一般推荐将Struts2常量集中在struts.xml文件中进行管理。

c) 使用<bean>标签配置Bean组件

Struts2框架是一个高度可扩展性的框架,框架大部分核心组件,Struts2并非以硬编码的方式写在代码中的,而是以本身的IOC容器来管理框架的核心组件。

Struts2框架以可配置的方式来管理Struts2的核心组件,从而容许开发者能够很方便地扩展该框架的核心组件。当开发者须要扩展,或者替换Struts2的核心组件时,只须要提供本身的组件实现类,并将该组件实现类配置在Struts2的IOC容器中便可。

在strus.xml文件中定义Bean时,一般有两个做用:

1) 建立该Bean的实例,将该实例做为Struts2框架的核心组件使用;

2) Bean包含的静态方法须要注入一个值;

在第一种用法下,由于Bean实例每每是做为一个核心组件使用的,所以须要告诉Struts2容器该实例的做用-就是该实例实现了哪一个接口,这个接口每每定义了该组件作必须遵照的规范,配置以下图所示:

clip_image018

在第二种用法下,则能够很方便容许不建立某个类的实例,却能够接受框架常量,一般须要设置static=true。

clip_image020

小提示:

对于绝大部分Struts2应用而言,咱们无需从新定义Struts2框架的核心组件,也就无需在Struts.xml文件中定义Bean。

在使用<bean/>元素在struts.xml文件中定义Bean,bean元素有如下几个属性:

class:必填属性,它指定了Bean实例的实现类。

type:可选属性,它指定了Bean实例实现的Struts2的规范,该规范

一般是经过某个接口或者在此前定义过的Bean,所以该属性值一般是个接口或者此前定义过的Bean的name属性值。若是须要将Bean的实例做为Strut2组件使用,则应该指定该属性的值。

name:可选属性,它指定的Bean实例的名字,对于有相同type的多个Bean。则它们的name属性不能相同。

scope:可选属性,它指定Bean实例的做用域,该属性的值只能是default、singleton、request、session或thread之一。

static:可选属性,它指定Bean是否使用静态方法注入。一般而言,当指定了type属性时,该属性就不该该指定为true。

optional:可选属性,它指定Bean是不是一个可选Bean。

d) 使用<package>标签配置包

Struts2框架中核心组件就是Action、Interceptor、Result等,Struts2使用包来管理。每一个包就是多个Action、多个Interceptor、多个Result、多个Interceptor引用的集合。

属性

必需

描述

name

包名,做为其它包应用本包的标记

extends

设置本包继承其它包

namespace

设置包的命名空间

abstract

设置为抽象包

1. name属性:必填属性,指定包的名字,该名字是该包被其余包引用的key;

2. abstract属性:该属性为true时,该包为抽象包,抽象包不能包含Action定义;

2. extends属性:当一个包经过配置extends属性继承了另外一个包时,该包将会继承父包中全部的配置,包括action、result、interceptor等;因为包信息的获取是按照配置文件的前后顺序进行的,且Struts2配置文件是从上到下处理的,因此父包应该在子包前面定义;一般咱们配置struts.xml时,都继承一个名为“struts-defaul”

的包,该包是struts2内置的包。

3. namespace属性:该属性针对大型项目中Action的管理,更重要的是解决Action重名问题,同一个命名空间里不能有同名的Action,不一样的命名空间能够有同名的Action。

<package>标签具体配置,以下图所示:

clip_image022

4. Struts2若是没有为某个包指定命名空间,该包使用默认的命名空间,默认的命名空间老是"";

5. Struts2还能够显示指定根命名空间,经过设置包的namespace="/"来指定根命名空间;

6. Struts2会按顺序在命名空间中搜索请求的Action,以下:命名空间只有一个级别。若是请求的URL是/bookservice/search/get.action,系统将先在/bookservice/search的命名空间下查找名为get的Action,若是查找到,则有该Action处理;若是未查找到,系统直接进入默认的命名空间查找名为get的Action,而不会在/bookservice的命名空间下查找名为get的Action;

小提示:

查找Action会根据URL对应的命名空间(可能会是根命名空间)查找Action,若没有,则会在默认命名空间里查找。

7. Struts2默认命名空间和根命名空间二者区别:

默认的命名空间namespace="",根命名空间namespace="/";

clip_image024

若是未指定命名空间,则命名空间默认为namespace=""。默认命

名空间里的Action能够处理任何命名空间下的Action请求,而根命名空间里的Action只处理根命名空间下的Action请求。

Struts2查找对应的Action时,会根据URL首先在对应的命名空间下查找,若未查找到,则继续会在默认命名空间下查找。

e) 使用<interceptor-stack>、<interceptors>、<interceptor>标签配置拦截器

拦截器其实就是AOP的编程思想。拦截器容许在Action处理以前,或者Action处理以后,插入开发者自定义的代码。

一般,使用拦截器能够完成以下操做:进行权限控制、跟踪日志、跟踪系统的性能瓶颈。

Struts2容许多个拦截器组合在一块儿,造成一个拦截器栈。一个拦截器栈能够包含多个拦截器,多个拦截器组成一个拦截器栈。对于Struts2系统而言,多个拦截器组成的拦截器栈对外也表现成一个拦截器。

能够认为多个拦截器组成拦截器栈是一个大的拦截器。Struts2推荐定义多个小粒度的拦截器,而后组合成拦截器栈来完成复杂的功能,而不是直接定义大粒度拦截器。同一个小粒度的拦截器,能够与其余不一样的拦截器组成不一样的拦截器栈,从而提供更好的复用性。

定义拦截器栈以前,必须先定义组成拦截器栈的多个拦截器,相关配置以下图所示:

clip_image026

在package元素节点下,设置Action默认拦截器引用:

clip_image028

小提示:

使用<default-interceptor-ref>标签能够为其所在的Action添加默认拦截器功能。当为某个Action单独添加拦截器功能后,<default-interceptor-ref>中所指定的默认拦截器将再也不对这个Action起做用,须要再次手动添加默认拦截器引用。

f) 使用<action>标签配置业务控制器Action

1. 实现Action处理类

相对于Struts1而言,Struts2采用了低侵入式的设计,Struts2不要求Action类继承任何的Struts2基类,甚至不要求实现任何Struts2接口,在这种设计方式下,Struts2的Action类是一个普通POJO类(一般应该包含一个无参数的execute方法),Struts2会默认执行该类的execute方法,从而有很好的代码复用性。这正如HelloWord应用中的Action实现类。

Struts2一般直接使用Action来封装Http请求参数,以下图所示:

clip_image030

小提示:

即便Action须要处理的请求包含username和password两个HTTP参数,Action类也能够不包含username和password属性。由于系统是经过对应的getter和setter方法来处理请求参数的,而不是经过属性名来处理请求参数的。也就是说,若是包含username的HTTP请求参数,Action类里是否包含username属性并不重要,重要的是需要包含setter和getter两个方法。

Action类里的属性,不只用于封装请求参数,还能够用于封装处理结果。对系统而言,封装请求参数的属性和封装处理结果的属性是彻底平等的。

若是HTTP请求里包含了名为username的请求参数,系统会调用Action类的setUsername方法,经过这种方法,名为username的请求参数就能够传递给Action实例;若是Action类里没有包含对应的set方法,则请求参数没法传入该Action。

一样,在jsp页面中输出Action属性username时,系统会调用Action类的getUsername方法,系统不会区分该属性是用于封装请求参数的属性仍是用于封装处理结果的属性。所以,使用Struts2的标签既能够输出Action的处理结果,也能够输出HTTP请求参数值。

2. Action接口与ActionSupport类

虽然Struts2没有要求Action必须实现特定接口或继承特定类,但为了让用户开发的Action类规范,Struts2提供了一个Action接口,这个接口定义了Struts2的Action处理类应该实现的规范,开发者的Action类能够实现该接口。下面是标准Action接口的代码:

clip_image032

Struts2还为Action接口提供了一个实现类:ActionSupport,下面是该ActionSupport实现类的代码:

clip_image034

clip_image036

小提示:

ActionSupport是一个默认的Action类,该类已经提供了许多默认的方法,这些默认方法包括获取国际化信息的方法、数据校验的方法、默认的处理用户请求的方法等。实际上,ActionSupport类彻底能够做为Struts2应用的Action处理类(由于它已经实现了execute方法),若是让开发者的Action类继承该ActionSupport类,则会大大简化Action的开发。

因为ActionSupport彻底可做为Struts2应用的Action处理类,所以当用户配置Action类没有指定class属性时,系统会自动使用ActionSupport类做为Action默认的处理类。此时,该Action老是返回“success”字符窜做为逻辑视图名。配置Action默认的处理类,以下图所示:

clip_image038

3. Action访问Servlet API

Struts2的Action并未直接与任何Servlet API耦合,这是Struts2的一个改良之处,由于Action类再也不与Servlet API耦合,从而能更轻松地测试该Action。

但对于Struts2应用中控制器而言,除了将请求参数自动设置到Action的字段中,不访问Servlet API几乎是不可能的。Struts2应用中一般须要访问的Servlet API就是HttpServletRequest、HttpSession和ServletContext,这3个类分别表明JSP内置对象中的request、session和application。Struts2一般会如下面两种方式,访问Servlet API:

非IOC方式

经过以非IOC的方式访问上述对象,关键是要经过Struts 2中com.opensymphony.xwork2.ActionContext类的方法得到Struts2封装的Servlet API的Map对象。

ActionContext是一个Action的上下文对象,Action运行期间所用到的数据都保存在ActionContext中(如Session,客户端提交的参数等信息)。上下文能够看做是一个容器(其实咱们这里的容器就是一个Map而已),它存放的是Action在执行时须要用到的对象,好比:在使用WebWork时,咱们的上下文放有请求的参数(Parameter)、会话(Session)、Servlet上下文(ServletContext)、本地化(Locale)信息等。在Action中能够经过下面的代码来建立和使用ActionContext类,关于该类的方法介绍以下所示:

ActionContext ac=ActionContext.getContext();//获取ActionContext对象

1.Object get(Object key) :经过参数key来查找当前ActionContext中的对应的value。该方法可获取HttpServletRequest属性。
2.Map getApplication() :返回一个Application级的Map对象,该对象模拟了该应用的ServletContext实例。
3.Static ActionContext getContext() :静态方法,得到当前线程的ActionContext对象。
4.Map getParameters() :返回一个包含全部HttpServletRequest参数信息的Map对象 。
5.Map getSession() :返回一个Map类型的HttpSession对象,该对象模拟了HttpSession实例。
6.Void put(Object key,Object value) :向当前ActionContext对象中存入键值对信息,该方法可用于向HttpServletRequest里存入属性。
7.Void setApplication(Map application) :直接传入一个Map实例,将该Map实例里的key-value对转换成application的属性名、属性值,以设置Application上下文对象。
8.Void setSession(Map session) :直接传入一个Map实例,将该Map实例里的key-value对转换成session的属性名、属性值。

小提示:

1.WebWork框架将与Web相关的不少对象从新进行了包装,好比这里就将HttpSession对象从新包装成了一个Map对象,供咱们的Action使用,而不用直接和底层的HttpSession打交道。也正是框架的包装,让咱们的Actoion能够彻底的和Web层解藕。

2.ActionContext有一个内置的map,全部的参数都保存在这个map中,其中就有valuestack;

3.在每次执行Action以前都会建立新的ActionContext,ActionContext是线程安全的,也就是说在同一个线程里ActionContext里的属性是惟一的,这样个人Action就能够在多线程中使用。ActionContext中有个静态的ThreadLocal变量,用来存放每一个Action的actionContext。以下图所示:

clip_image040

ActionContextThreadLocal是实现ThreadLocal的一个内部类。ThreadLocal能够命名为“线程局部变量”,它为每个使用该变量的线程都提供一个变量值的副本,使每个线程均可以独立地改变本身的副本,而不会和其它线程的副本冲突。这样,咱们ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的。

非IOC方式实现Action,如图所示:

clip_image042

显然,相比Struts1中直接访问Servlet API,Struts2经过ActionContext访问Servlet API更加优雅。让Action完全从Servlet API中分离出来,从而能够容许该Action脱离Web容器运行。最大的好处:能够脱离Web容器测试。

另外,为了直接访问Servlet API,Struts2提供了一个ServletActionContext,这个类包含了几个静态方法:

PageContext getPageContext():取得Web应用Http页面的PageContext对象。

HttpServletRequest getRequest():取得Web应用HttpServletRequest

对象。

HttpServletResponse getResponse():取得Web应用的

HttpServletResponse对象。

ServletContext getServletContext():取得Web应用的ServletContext对象。

具体使用,相关代码如图所示:

clip_image044

小提示:

借助ServletActionContext类的帮助,开发者也能够在Action中直接访问Servlet API,避免Action类须要实现XXXAware接口,虽然如此,此种方式仍不被推荐,该Action依然与Servlet API直接耦合,同样不利于程序解耦。

IOC方式

要使用IOC方式,一般首先要告诉IOC容器想取得某个对象的意愿,经过实现对应的接口能够作到这点。

ServletContextAware:实现了该接口的Action能够直接访问web应用的ServletContext实例。

SerlvetRequestAware:实现了该接口的Action能够直接访问webDe HttpSerlvetRequest实例。

ServletResponseAware:实现了该接口的Action能够直接访问服务器的相应的HttpServletResponse对象。

若是实现了ServletResponseAware只须要实现之中的public void setServletResponse(HttpServletResponse response)方法便可,而后就可使用httpServletResponse对象进行操做。ServletRequestAware对象也是这样的。

相关代码如图所示:

clip_image046

小提示:

必须指出,虽然能够在Action类中获取HttpServletResponse,但若是但愿经过HttpServletResponse来生成服务器响应是不可能的,由于Action只是控制器。即若是在Action中书写以下代码:

response.getWrite().println("Hello World");

上面代码在标准Servlet中会生成对客户端的输,但在Struts2的Action中,没有任何实际意义。

因此即便咱们在Struts2的Action类中得到了HttpServletRequest对象,也不要尝试直接在Action中生成对客户端的输出。由于那很没意义。

4. 配置Action

一旦提供了Action的实现类后,就能够在struts.xml文件中配置该Action。配置Action就是让Struts2容器知道该Action的存在,而且可以调用该Action来处理用户请求。所以,Action是Struts2的基本“程序单位”。

<action>属性介绍

属性名称

是否必须

功能描述

name

请求的Action名称

class

Action处理类对应具体路径

method

指定Action中的方法名

converter

指定Action使用的类型转换器

1. name属性:必选属性,指定该Action的名字,也同时指定该Action须要处理的URL的后半部分,如:URL为/bookservice/search/get.action,则name应该为get;等同于Struts1中Action的path属性。

若是须要在name属性中使用斜线(/),则须要指定Struts2框架容许Action name中出现斜线。配置如图所示:

clip_image048

若是咱们但愿Struts2应用能够列出Web应用根路径下的全部页面,则能够在struts.xml文件中配置一个name=””的Action,该Action就能够处理列出Web应用根路径下的全部文件请求。配置以下图所示:

clip_image050

此外,还须要保证Web容器自己能够列出根路径下全部文件。好比Tomcat 5.五、6.0,它默认是不会列出的。因此要修改Tomcat的conf/web.xml文件98行的listings参数,将其修改成true。

2. class属性:可选属性,指定该Action的实现类。若未指定class属性,系统则默认使用系统的ActionSupport类。

3. method属性:可选属性,指定Action处理请求的方法名。若未指定method属性,则Action处理请求默认执行execute方法。

4. 动态方法调用:能够采用DMI调用来处理这种请求。动态方法调用是指表单元素的action并非直接等于某个Action的名字。而是以以下来指定Form的action属性:

action=”action!methodName.action”(若以/开始,则为绝对路径;不然为相对路径。)

使用动态方法调用前必须设置Struts2容许动态方法调用。配置以下:

clip_image052

5. 使用通配符:在配置<action>元素时,须要指定name、class和method属性,其中name属性可支持通配符,而后能够在class、method属性中使用表达式。这种使用通配符的方式是另外一种形式的动态方法调用。

clip_image054

实际上,Struts2不只容许在class、name、method属性中使用表达式,还能够在<result>元素中使用表达式。

使用通配符模式配置Action时,URL与 Action的匹配规则以下:由于除非请求的URL与Action的name属性绝对相同,不然,将按前后顺序来决定由哪一个Action来处理用户请求。所以,咱们应该将名为星号“*”的Action配置在最后,不然Struts2将使用该Action来处理全部但愿使用通配符匹配的请求。

6. 配置默认Action

对于使用Struts2框架的应用而言,尽可能不要让超连接直接连接到某个视图资源,由于这种方式增长了额外的风险。推荐将全部请求都发送给Struts2框架,让该框架来处理用户请求,即便只是简单的超连接。

对于只是简单的超连接的请求,能够经过定义name为*的Action(该Action应该放在最后位置定义)实现。除此以外,Struts2还容许在容器中定义一个默认的Action,当用户请求的URL在容器中找不到对应的Action时,系统将使用默认Action来处理用户请求。相关配置如图所示:

clip_image056

<action>具体配置

clip_image058

小提示:

Action只是一个控制器,它并不会像Servlet那样直接对浏览者生成任何响应。因此,在Action中,任何的response输出都是无效的,非法的,所以,Action处理完用户请求后,Action须要将指定的视图资源呈现给用户,所以,配置Action时,应该配置逻辑视图资源和物理视图资源之间的映射。

j) 使用<result>标签配置返回结果

配置逻辑视图资源和物理视图资源之间的映射关系是经过<result>元素来定义的,每一个<result>元素定义逻辑视图和物理视图之间的一次映射。

Action处理完用户请求后,并未直接将请求转发给任何具体的视图资源,而是返回一个逻辑视图,Struts2框架收到这个逻辑视图后,把请求转发到对应的视图资源,视图资源将处理结果呈现给用户。

简单的说,结果是告诉Struts2框架,当Action处理结束时,系统下一步作什么。当Action返回一个普通字符串时,系统下一步将作什么。

局部结果:将<result>做为<action>元素的子元素配置;

全局结果:将<result>做为<global-results>元素的子元素配置;

<result>属性介绍

属性名称

是否必须

功能描述

name

对应Action返回逻辑视图名称,默认为success

type

返回结果类型,默认为dispatcher

parse

指定是否容许在实际视图名字中使用OGNL表达式,默认为true。

小提示:

1. Struts2默认的结果类型是dispatcher,但咱们能够经过修改配置文件,改变默认的结果类型。一旦改变了默认的结果类型,若是配置<result>元素时省略type元素时,则意味着使用默认的结果类型。

2. 若是配置<result>元素时没有指定location参数,系统将会把<result>…</result>中间的字符串当成实际视图资源;

若是没有指定name属性,则name属性采用默认值:success;

若是没有指定type属性,则采用Struts2的默认结果类型;

3. 全局结果的做用范围是对全部的Action都有效;局部结果的做用范围仅是当前Action有效。

4. 若是一个Action里包含了与全局结果里同名的结果,则Action里的局部Action会覆盖全局Action。也就是说,当Action处理用户请求结束后,会首先在本Action里的局部结果里搜索逻辑视图对应的结果,只有在Action里的局部结果里找不到逻辑视图对应的结果,才会到全局结果里搜索。

<result>具体配置

1. 全局结果配置

clip_image060

2. 局部结果配置

clip_image062

h) 使用<result-type>标签配置返回结果类型

Struts2支持使用多种视图技术,如:JSP、Velocity和FreeMarker等。当一个Action处理用户请求结束后,仅仅返回一个字符串,这个字符串只是逻辑视图名,该逻辑视图并未与任何的视图技术及任何的视图资源关联,直到咱们在struts.xml文件中为该逻辑视图指定实际的视图资源。

结果类型决定了Action处理结束后,下一步将执行哪一种类型的动做。

Struts2的结果类型要求实现com.opensymphony.xwork.Result接口,是全部Action执行结果的通用接口。若是咱们须要本身的结果类型,咱们应该提供一个实现该接口的类,而且在struts.xml文件中配置该结果类型。

如下列出Struts2框架自带的几种结果类型配置,并作了简要说明,如图所示:

clip_image064

k) 使用<global-exception-mapping>、<exception-mapping>标签配置异常映射

clip_image066

l) 使用<unknown-handler-stack>与<unknown-handler-ref>标签配置未知处理器

clip_image068

相关文章
相关标签/搜索