第三节(下):struts.xml文件配置详解

来源:互联网 发布:linux命令行脚本 编辑:程序博客网 时间:2024/06/04 18:46

一.bean元素

作用:

1.创建该Bean的实例,将该实例作为Struts2框架的核心组建使用。框架大部分核心组件Struts2并不是直接以硬编码的方式写在代码中的,而是以自己的IOC(依赖注入、控制反转容器)来管理框架的核心组件。从而允许开发者可以非常方便的扩展该框架的核心组件,当开发者需要扩展,或者替换Struts2的核心组件的时候,只需要提供自己的组件实现类,并且将组件实现类部署在Struts2的IOC容器当中就可以了。

PS:对于绝大部分Struts2应用而言,我们无需重新定义Struts2框架的核心组件。

2.Bean包含的静态方法需要一个值注入。

实例

1.替换Struts2核心组件

我们使用自定义的ObjectFactory来替换Struts2内置的ObjectFactory。

<struts>
<!-- 配置定制的Objectfactory Bean,该Bean实现了ObjectFactory接口,实现类是MyObjectFactory -->
<bean type="com.opensymphony.xwork2.ObjectFacotry" name="myfactory" class="com.company.myapp.MyObjectFacotry"/>
</struts>
2.将自定义类依赖注入到Struts2中,可以在项目启动过程中被创建,并且可以控制类的初始化参数。

<struts>
<bean class="org.apache.struts2.dispatcher.FilterDispatcher" static="true"/>
</struts>

属性详解:

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

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

这个属性也是一个可选属性。

type:这个属性是个可选属性,它指定了Bean实例实现的Struts2规范,该规范通常是通过某个接口来体现的,

因此该属性的值通常是一个Struts2接口。如果需要将Bean实例作为Struts2组件来使用,则应该指定该属性值。

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

static:该属性值Bean是否使用静态方法注入。通常而言,当指定了type属性时,该属性不应该指定为true。

optional:该属性指定该Bean是否是一个可选Bean,该属性是一个可选属性。


二。常量配置constant 

说明:

在struts.xml中配置struts.properties文件中的配置信息。

PS:通常推荐在struts.xml文件中定义Struts2属性,而不是在struts.properties文件中定义Struts2属性。其实还可以在web.xml文件中配置,但很不推荐。

通常,Struts2框架按如下搜索顺序加载struts2常量;

1.struts-default.xml:该文件保存在struts2-core-xxx.jar文件中。

2.struts-plugin.xml:该文件保存在struts2-xxx-xxxx.jar等Struts2插件JAR文件中。

3.struts.xml:该文件是Web应用默认的Struts配置文件。

4.struts.properties:该文件是Web应用默认的Struts2配置文件。

5.web.xml:该文件是Web应用的配置文件。

如果在多个文件中配置了同一个Struts2常量,则最后一个文件中配置的常量值会覆盖前面文件中配置的常量值。

实例:

在struts.xml文件中配置的方法:

<struts>
<!-- 通过 constant元素配置 -->
<constant name="struts.custom.i18n.resources" value="mess"/></struts>
在struts.properties文件中配置的方法

struts.i18n.encoding=UTF-8
在web.xml文件中配置

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  <filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class><init-param><param-name>struts.custom.i18n.resources</param-name><param-value>messageResource</param-value></init-param></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping>    <welcome-file-list>    <welcome-file>Login.jsp</welcome-file>  </welcome-file-list></web-app>

三。包配置package

说明:

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

配置包时,必须指定name属性,这个属性是引用该包的key。还可以指定一个可选的extends属性,extends属性值必须是另一个包的name属性。指定extends属性表示让该包继承其他包,子包可以继承一个或多个父包中的拦截器、拦截器栈、action等配置。

除此之外,Struts2还提供了一种所谓的抽象包,抽象包中不能包含Action定义。可以为该package元素增加abstract="true"属性来彰显该包是抽象包。


属性详解:

name:这事一个必填属性,该属性指定该包的名字,该名字是该包被其他包引用的key。

extends;该属性是一个可选属性,该属性指定该包继承其他包。继承其他包,可以继承其他包中的Action定义、拦截器定义等。

namespace;该属性是一个可选属性,该属性定义该包的命名空间。

1.namespace的格式是"/开头",单独用x不行,要设置为/x

2.namespace可以重名。但只有一个生效,最后的配置会覆盖之前的配置。

abstract:该属性是一个可选属性,他指定该包是否是一个抽象包。抽象包中不能定义Action。


四。命名空间配置

说明:

考虑到同一个Web应用中需要同名的Action,Struts2以命名空间的方式来管理Action,同一个命名空间里不能有同名的Action,不同的命名空间里可以有同名的Action。

Struts2不支持为单独的Action设置命名空间,而是通过为包指定namespace属性来为包下面的所有Action指定共同的命名空间。

如果一个包未指定namespace属性,即该包使用默认的命名空间,默认命名空间为“”。

当某个包指定了命名空间后,该包下所有Action处理的URL应该是命名空间+Action名。例如包名为/book,Action名为getBook。则访问该action的URL为http://xxxxxxx/book/getbook.action

除此之外,Struts2还可以显示指定根命名空间,通过设置某个包的namespace="/"来指定根命名空间。根命名空间与默认命名空间是不一样的。

命名空间只有一个级别。

实例:

bar.action:在默认命名空间中查找。

/bar.action:现在“/”根命名空间中查找,再到默认命名空间中查找。

/barspace/bar.action:先在barspace命名空间中查找,再到默认命名空间中查找。

/barspace/search/bar.action:先在barspace命名空间中查找,再到默认命名空间中查找。

五。包含配置

说明:

包含配置体现的是软件工程中“分而治之”的原则。

Struts2允许将一个配置文件分解成多个配置文件,从而提供配置文件的可读性。一旦分解则需要在struts.xml中将分解的文件导入。

实例:

<struts><include file="文件名称"/><include file="文件名称"/></struts>


六。拦截器配置
说明:
拦截器其实就是AOP(面向切面编程)的编程思想。拦截器允许在Action处理之前或者Action处理结束之后,插入开发者自定义的代码。
在很多时候,我们需要多个Action进行相同的操作,例如权限管理,此处就可以使用拦截器来检查用户是否登录,用户的权限是否足够。
例如:
进行权限控制
跟踪日志
跟踪系统的性能瓶颈(我们可以通过记录每个Action开始处理时间和结束时间,从而获取耗时较长的Action)
实例:
定义拦截器和拦截器栈
<!-- 该元素可以出现,也可以不出现,最多出现一次 -->          <interceptors>              <!-- 该元素的interceptor元素和interceptor-stack至少出现其中之一,              也可以两者都出现 -->              <!-- 下面元素可以出现0次,也可以出现无限多次 -->              <interceptor name="" class="">                  <!-- 下面元素可以出现0次,也可以出现无限多次 -->                  <param name="参数名">参数值</param>              </interceptor>              <!-- 下面元素可以出现0次,也可以出现无限多次 -->              <interceptor-stack name="">                  <!-- 该元素必须出现,可以出现无限多次 -->                  <interceptor-ref name="">                      <!-- 下面元素可以出现0次,也可以无限多次 -->                      <param name="参数名">参数值</param>                  </interceptor-ref>              </interceptor-stack>          </interceptors>

使用拦截器

<action name="MyAction" class"my.NyAction"><result name="success">...</result><interceptor-ref name="authorityandlog"/><action>
七。Action

1.当用户配置Action类没有指定class属性时,系统自动使用ActionSupport类作为默认的Action处理类。
普通类就可以作为Action的类,在处理请求响应。String2提供了一些接口、类等来便于开发者开发。
2.Action的name属性的命名规则。不推荐在Action的name属性值中使用(.)(-)。
接口:
Action
该接口中定义了一系列的结果字符串,如error、input、success等。
还提供了一个方法execute()定义,来等待开发者实现。
类:
ActionSupport
该接口实现了Action,Validateable,ValidationAware,TextProvider,LocaleProvider,Serializable接口,包含以下方法的实现
//收集校验错误的方法
public void setActionErrors(Collection errorMessages){
      validationAware.setActionErrors(errorMessages);
}
//返回校验错误的方法

public Collection<String> getActionErrors() {return ValidationAware.getActionErrors();}


//设置表单域校验错误信息

public void setFieldErrors(Map<String, List<String>> errorMap) {validationAware.setFieldErrors(errorMap);}


//返回表单域校验错误信息

public Map<String, List<String>> getFieldErrors() {return validationAware.getFieldErrors();}
//控制locale的相关信息
public Locale getLocale() {return actionContext.getContext().getLocale();}
//返回国际化信息的方法
public String getText(String textName) {return textProvider.getText(textName);}
//用于访问国际化资源包的方法

public ResourceBundle getTexts() {return textProvider.getTexts();}
//添加错误信息
public void addActionError(String anErrorMessage) {validationAware.addActionError(anErrorMessage);}
//添加字段校验失败的错误信息

public void addFieldError(String fieldName, String errorMessage) {validationAware.addFieldError(fieldName,errorMessage);}
//默认的input方法,直接返回input字符串
public String input() throws Exception {return INPUT;}
//默认的处理用户请求的方法,直接返回success字符串
public String execute() throws Exception {return SUCCESS;}
//清除所有错误信息的方法
public void clearErrorsAndMessages() {validationAware.clearErrorsAndMessages();}
//包含空的输入校验方法
public void validate() {}
2.Action访问Servlet API
Web应用中通常需要访问的Servlet API就是HttpServletRequest、HttpSession和ServletContext,这三个类分别代表JSP内置对象中的request、session和appliaction。
Struts2提供了一个ActionContext类,Struts2的Action可以通过该类来访问Servlet API。以下是ActionContext类中包含的几个常用的方法:
Object get(Object key):该方法类似于调用HttpServletRequest的getAttribute(String name)方法。
Map getApplication():返回一个Map对象,该对象模拟了该应用的ServletContext实例。
static ActionContext getContext():静态方法,获取系统的ActionContext实例。
Map getParameters():获取所有的请求参数。类似于调用HttpServletRequest对象的getParameterMap方法。
Map getSession():返回一个Map对象,该Map对象模拟了HttpSession实例。
void setApplication(Map application):直接传入一个MAP实例,将该Map实例里的key-value对转换成application的属性名、属性值。
void setSession():直接传入一个MAP实例,将该Map实例里的key-value对转换成session的属性名、属性值。
例如:在action类execute()方法中
//获取ActionContext实例,通过该实例访问Servlet API
ActionContext ctx = ActionContext.getContext();
//获取session
cxt.getSession();
//保存session
cxt.setSession(session);
//获取request值
cxt.get(key);
//保存request值
cxt.put(key, value);


3.Action直接访问Servlet API
虽然Struts2提供了ActionContext来访问Servlet API,但这种访问毕竟不能直接获得Servlet API实例,为了在Action直接访问Servlet API,Struts2还提供了如下系列接口。
ServletContextAware:实现该接口的Action可以直接访问web应用的ServletContext实例。
ServletRequestAware:实现该接口的Action可以直接访问用户请求的HttpServletRequest实例。
ServletResponseAware:实现该接口的Action可以直接访问服务器响应的HttpServletResponse实例。


4.动态方法调用
DIM(Dynamic Method Invocation,动态方法),就是在访问URL时使用如下格式:ActionName!methodName.action
struts-2.3.15.3-all默认将该功能关闭了。但可以通过struts.properties开启。
5.为action元素指定method属性
略过。。。
6.使用通配符
在配置action元素时,需要指定name、class和method属性,这三个属性都可支持通配符,这种使用通配符的方式是另一种形式的动态方法调用。
例如:

<action name="*Action" class="com.messageAction" method="{1}"><!-- 定义了三个result --><result name="input">/a.jsp</result><result name="error">/b.jsp</result><result name="success">/c.jsp</result></action>当访问URL为loginAction时,调用com.messageAction类的login方法。<action name="*_*Action" class="com.{1}Action" method="{1}"><!-- 定义了三个result --><result name="input">/a.jsp</result><result name="error">/b.jsp</result><result name="success">/c.jsp</result></action>当访问URL为login_messageAction时,调用com.loginAction类的message<!-- 使用通配符配置了Action名,method属性是个动态值 --><action name="*"><!-- 定义了三个result --><result name="input">/{1}.jsp</result></action>当访问URL为abc.action时,则跳转到abc.jsp页面

defAction.action的请求,struts.xml文件中同样配置了abcAction、*Action和*三个Action,defAction.action的请求显然不会被name为abcAction的Action处理,但到底是那个?
结果:根据struts.xml中对以上三个配置的顺序而言,先配置的先匹配。

7.默认Action
Struts2还允许在容器中定义一个默认的Action,当用户请求的URL在容器中找不到对应的Action时,系统将使用默认的Action来处理用户请求。通过default-action-ref进行配置。

<default-action-ref name="strutsAction"></default-action-ref><!-- 使用通配符配置了Action名,method属性是个动态值 --><action name="strutsAction" class="com.messageAction" method="{1}"><!-- 定义了三个result --><result name="input">/a.jsp</result><result name="error">/b.jsp</result><result name="success">/c.jsp</result></action>
8.配置结果
Struts2的Action处理用户请求结束后,返回一个普通字符串——逻辑试图名,必须在struts.xml文件中完成逻辑视图和物理视图资源的映射,才可让系统转到实际的视图资源。
局部结果:将<result.../>作为<action.../>元素的子元素配置。
全局结果:将<result.../>作为<global-results.../>元素的子元素配置。
局部结果:详细配置
<result name="success" type="dispatcher"><param name="location">/thank_you.jsp</param><param name="parse">true</param></result>
属性详细:
name:定义逻辑视图资源映射名。
type:结果类型,
location:该参数指定了该逻辑视图对应的实际视图资源。
parse:该参数指定是否允许在实际视图名称中使用OGNL表达式,该参数值默认为true。如果设置该参数值为false,则不允许在实际视图名中使用表达式。通常无需修改该属性值。
局部结果:普通配置
<action name="getBooks" class="action.GetBooksAction"><result name="success">/showBooks.jsp</result></action>
省去type:默认值为dispatcher
省去name默认值为success
9.Struts2支持的处理结果类型
Struts2支持使用多种视图技术,例如JSP、Velocity和FreeMarker等。
Struts2的结果类型要求实现com.opensymphony.xwork.Result,这个结果是所有Action执行结果的通用接口。如果我们需要自己的结果类型,我们应该提供一个实现该接口的类,并且在struts.xml文件中配置该结果的类型。
dispatcher结果类型:用户JSP整合的结果类型。

chain结果类型:Action链式处理的结果类型。从一个Action处理内部跳转到另一个Action,每个Action的拦截器都会执行。

可以通过<param>标签向下一个Action传值。

固定参数说明:

actionName (默认) - 被调用的action的名字
namespace - 被调用的action的名称空间. 如果名称空间为空,这默认为当前名称空间
method - 用于指定目标action的另一个方法被调用. 如果空,默认为excute方法

实例:

<!-- 定义拦截器 --><interceptors><interceptor name="simple" class="intercepter.SimpleInterceptor"><param name="name">小拦截器(定义位置A)</param></interceptor></interceptors><action name="Login" class="action.LoginAction"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="simple"><param name="name">小拦截器(定义位置Login)</param></interceptor-ref><result name="error" type="chain"><param name="actionName">Chain</param><param name="namespace">/x</param></result></action><action name="Chain" class="action.ChainAction"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="simple"><param name="name">小拦截器(定义位置Chain)</param></interceptor-ref><result name="success" >/Login.jsp</result></action>
请求Login.action,由action.LoginAction类处理,返回"INPUT"字符串,请求从Login处理过程中跳转到Chain.action由action.ChainAction类处理。

LoginAction和ChainAction的execute均有一个数据语句,证明执行通过。

simple拦截器中有一句输出,证明执行通过。

执行结果输出如下

1.拦截器输出(Login的拦截器开始)

2.LoginAction类处理信息输出

3.拦截器输出(Chain的拦截器开始)

4.ChainAction类处理信息输出

5.拦截器输出(Chain的拦截器结束)

6.拦截器输出(Login的拦截器结束)


redirect结果类型:用于直接跳转到其他URL的结果类型。(重定向,丢失请求参数等等)。

      从一个Action处理后跳转到另一个地址(丢失上一个请求的全部请求参数值),每个Action的拦截器都会执行。

可以通过<param>标签向下一个地址传值。

固定参数说明:

location (默认) - 跳转地址
parse - 默认为true. 如果设置为false, location参数不会被当作Ognl表达式解析.

<!-- 定义拦截器 --><interceptors><interceptor name="simple" class="intercepter.SimpleInterceptor"><param name="name">小拦截器(定义位置A)</param></interceptor></interceptors><action name="Login" class="action.LoginAction"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="simple"><param name="name">小拦截器(定义位置Login)</param></interceptor-ref><result name="error" type="redirect"><param name="location">/x/Chain.action</param></result></action><action name="Chain" class="action.ChainAction"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="simple"><param name="name">小拦截器(定义位置Chain)</param></interceptor-ref><result name="success" >/Login.jsp</result></action>
请求Login.action,由action.LoginAction类处理,返回"ERROR"字符串,请求从Login处理结束后跳转到Chain.action由action.ChainAction类处理。

LoginAction和ChainAction的execute均有一个数据语句,证明执行通过。

simple拦截器中有一句输出,证明执行通过。

执行结果输出如下

1.拦截器输出(Login的拦截器开始)

2.LoginAction类处理信息输出

3.拦截器输出(Login的拦截器结束)


4.拦截器输出(Chain的拦截器开始)

5.ChainAction类处理信息输出

6.拦截器输出(Chain的拦截器结束)


redirect-action结果类型:用于直接跳转到其他Action的结果类型。(重定向,丢失请求参数等等)

此type值根据不同Struts2版本而不同:2.3为redirectAction,其他版本还有redirectaction、redirect-action等。

启动失败提示如下There is no result type defined for type 'redirect-Action' mapped with name 'error'.  Did you mean 'redirectACtion'?则表示type值问题。


可以通过<param>标签向下一个Action传值。

固定参数说明

actionName (默认) - 重定位到的action名
namespace - action的名称空间. 如果为null,则为当前名称空间

<!-- 定义拦截器 --><interceptors><interceptor name="simple" class="intercepter.SimpleInterceptor"><param name="name">小拦截器(定义位置A)</param></interceptor></interceptors><action name="Login" class="action.LoginAction"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="simple"><param name="name">小拦截器(定义位置Login)</param></interceptor-ref><result name="error" type="redirectAction"><param name="actionName">Chain</param><param name="namespace">/x</param></result></action><action name="Chain" class="action.ChainAction"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="simple"><param name="name">小拦截器(定义位置Chain)</param></interceptor-ref><result name="success" >/Login.jsp</result></action>

请求Login.action,由action.LoginAction类处理,返回"ERROR"字符串,请求从Login处理结束后跳转到Chain.action由action.ChainAction类处理。

LoginAction和ChainAction的execute均有一个数据语句,证明执行通过。

simple拦截器中有一句输出,证明执行通过。

执行结果输出如下

1.拦截器输出(Login的拦截器开始)

2.LoginAction类处理信息输出

3.拦截器输出(Login的拦截器结束)


4.拦截器输出(Chain的拦截器开始)

5.ChainAction类处理信息输出

6.拦截器输出(Chain的拦截器结束)


chart结果类型:用于整合JFreeChart的结果类型。

freemarker结果类型:用于FreeMarker整合的结果类型。
httpheader结果类型:用于控制特殊的HTTP行为的结果类型。
jasper结果类型:用于JasperReports整合的结果类型。
jsf结果类型:用于与JSF整合的结果类型。
stream结果类型:用于向浏览器返回一个InputStream(一般用于文件下载).
tiles结果类型:用于与Tiles整合的结果类型。
velocity结果类型:用于与Velocity整合的结果类型。
xslt结果类型:用于与XML/XSLT整合的结果类型。
plaintext结果类型:用于显示某个页面的原始代码的结果类型。
遇到过的结果类型:
json:用于返回json字符串,通过Ajax访问action后返回json字符串给ajax使用。


10.动态结果
我们可以想配置动态action那样配置动态的result。
1.配置<result.../>元素时使用表达式语法,从而允许根据请求动态决定实际资源。
<action name="getBooks_*" class="action.GetBooksAction" method="{1}"><result name="success">/{1}.jsp</result></action>
当请求URL为:getBooks_success.action时,调用action.GetBooksAction类的success方法,返回success字符串时动态访问到success.jsp页面。
2.配置<result.../>元素时,使用OGNL表达式。即形式为:${属性名.属性名.属性名},此处的属性名就是action中的属性。

<action name="getBooks" class="action.GetBooksAction"><result type="redirect-action" name="success">/getBook.action?skillName=${currentSkill.name}</result></action>
当请求URL到达action.GetBooksAction内处理,对currentSkill.name属性赋值为abc。返回字符串为success时,跳转到/getBook.action?skillName=abc的URL。
11.全局结果
全局结果:将<result.../>作为<global-results.../>元素的子元素配置。
局部结果会覆盖全部结果的有效性。


12.属性驱动和模型驱动
模型驱动:就是使用单独的javaBean实例来贯穿整个MVC流程;
属性驱动:就是使用action的属性作为贯穿整个MVC流程的信息携带者。
模型驱动使用时,Action必须实现ModelDriven接口,实现该接口则必须实现getModel方法,该方法用于把Action和与之对应的Model实例关联起来。
将URL请求参数转为action的属性或者action的模型,是通过Struts拦截器实现的。
将参数转为属性是通过

<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
将参数转为模型是通过
以上两个拦截器在默认拦截器栈中已被设置。
13.Struts2的异常机制
说明:
Struts2提供了一种声明式的异常处理方式。通过在struts.xml中配置<exception-mapping.../>元素完成。
action的execute方法定义public String execute() throws Exception,该方法将任何异常通通抛出去。在struts.xml中配置各种异常对应的物理页面地址。则当action抛出A异常时跳转到A异常对应的异常信息展现页面。
该功能由拦截器实现:在默认defaultStack拦截器栈中已配置。
<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>


局部异常映射:将<exception-mapping.../>元素作为<action.../>元素的子元素配置。
全局异常映射:将<exception-mapping.../>元素作为<global-exception-mapping.../>元素的子元素配置。
局部异常映射覆盖全局异常映射的效果。
实例:

<global-results><result name="sql">/sql.jsp</result><result name="root">/root.jsp</result></global-results><global-exception-mappings><exception-mapping result="sql" exception="java.sql.SQLException"></exception-mapping><exception-mapping result="root" exception="java.lang.Exception"></exception-mapping></global-exception-mappings><action name="getBooks" class="action.GetBooksAction"><exception-mapping result="my" exception="com.myException"></exception-mapping><result name="success">/showBooks.jsp</result><result name="login">/Login.jsp</result></action>
属性详解:
exception:此属性指定该异常映射所设置的异常类型。
result:此属性指定Action出现该异常时,系统转入result属性所指向的结果。
14.在页面中输出错误信息
<s:property value="exception"/>:输出异常对象本身。
<s:property value="exceptionStack"/>:输出异常堆栈信息。
exception是一个对象,所以打点调用该对象的属性进行输出。

                                             
0 0
原创粉丝点击