1)struts.xml的主要作用
其存放位置Web应用下的类加载路径下才能使用,即WEB-INF/classes路径下。Struts.xml文件主要用来配置Action和HTTP请求的对应关系,以及配置逻辑视图和物理视图资源的对应关系。除了这些功能之外,它还有一些额外的功能,如配置常量,导入其他配置文件等。
<struts../>是根标签,所有其他的标签都放在<struts></struts> 中间;package 元素定义了一个包,在 Struts 2框架中,用包来组织 Action 和拦截器等,每个包都是零个或多个拦截器以及Action 所组成的集合;action 元素定义了一个Action 和其对应的类;result 元素定义了Action 返回结果对应的JSP 视图。
2)struts.xml关键元素分析
1.package 元素
package 元素用来配置包。在Struts 2 框架中,包是一个独立的单位,通过name属性来唯一标识包。还可以通过指定extends属性让一个包继承另一个包,extends属性值就是被继承包的name属性值,继承包可以从被继承包那里继承到拦截器、Action 等。
package元素属性
属性 说 明
name 这是一个必须属性,标识包的名字,以便在其他包中被引用
extends 可选属性,指定该包继承自其他包
namespace 可选属性,指定命名空间,标识此包下的Action 的访问路径
abstract 可选属性,指定该包为抽象包
中可以看到,package 元素有一个namespace 属性,该属性可以指定包对应的命名空间。由于在一个Web 应用中可能出现同名的Action 并存的情况,为了避免命名冲突,只要使同名Action 位于不同的namespace 下就可以了。如果package 元素没有指定namespace 属性,则其下定义的所有Action 都处于默认的命名空间下。
下面以一个示例来说明package 命名空间属性的用法:
<!--配置名为A 的包,继承了struts-default,命名空间为默认的命名空间-->
<package name="A " extends="struts-default">
<action name="login" class="com.action.LoginAction">
<result name="login_success">/login_success.jsp</result>
</action>
</package>
<!--配置名为B 的包,继承了struts-default,命名空间为"/"-->
<package name="B" namespace="/" extends="struts-default">
<action name="exit" class="com.action.Exit Action">
<result name="exit_success">/exit_success.jsp</result>
</action>
</package>
<!--配置名为C 的包,继承了struts-default,命名空间为"/info"-->
<package name="C" namespace="/info" extends="struts-default">
<action name="stu" class="com.action.Stu Action">
<result name="stu_info">/stu_info.jsp</result>
</action>
</package>
在上面代码中,配置了两个包:A 和B 。对于包A,由于没指定命名空间,则其命名空间为默认命名空间;对于包B ,其命名空间是根命名空间;对于包C ,其命名空间则是“∕info ”。
当包指定命名空间后,该包所包含的Action 处理的URL 应该就是命名空间+Action名。
即包A 下名为login 的Action 处理的URL 是http://localhost:8080/login.action;包 B 下名为exit 的Action 处理的URL是http://localhost:8080/exit.action ;包C 下名为stu 的Action 处理的URL 是http://localhost:8080/info/stu.action,其中8080是笔者的Tomcat服务器的端口号。
对于URL 中指定的Action ,Struts 2 是按一定的顺序来查找的。如果要访问/C/stu_info.action,Struts 2框架首先查找/C 命名空间里名为stu_info 的Action ,如果该命名空间里找到对应的Action ,则使用其对应的Action 来处理请求;否则,Struts 2 框架到默认命名空间查找名为stu_info 的Action ,如果找到,则使用其对应的Action 来处理请求;如果两个命名空间里都找不到名为stu_info 的Action ,则系统出现错误。
另外,读者有两个要注意的地方:第一,根命名空间和普通命名空间中的 Action 的查找是一样的,即如果有请求/stu_info.action ,则先查找根命名空间下的 Action ,如果不存在对应的Action ,则查找默认命名空间里的Action 。第二,对于多级别的命名空间,Struts 2框架在最底层的命名空间里查找后,如果不存在相应的Action ,则会同样到默认命名空间里查找,而不是到上一级命名空间里查找。即如果请求为/A/A_Login/login.action 时,Struts 2 框架首先到/A/A_Login 的命名空间里查找名为login的Action ,如果找不到对应的Action ,则会到默认命名空间里查找,而不是到/A的命名空间里查找。
(2 )action 元素
Struts 2框架通过Action 对象来处理HTTP 请求,该请求的URL地址对应的Action 即配置在action 元素中,如下代码所示:
<action name="userAction" class=" com.action.UserAction">
<result>/user.jsp</result>
</action>
action 元素除了有name和class 属性外,还有 method和converter 属性,表 5.2 列出了action 元素的各个属性。
表5.2 action元素属性
属性 说 明
name 这是一个必须属性,标识Acton,指定了该Action 所处理的请求的URL
class 可选属性,指定Action 对象对应的实现类
method 可选属性,指定请求Action 时调用的方法
converter 可选属性,指定类型转换器的类
在配置 action 元素时,如果没有指定class 属性值,则其默认值为类com.opensymphony.xwork2.ActionSupport ,该默认类会使用默认的处理方法execute() 来处理请求。实际上,execute() 方法不会做任何处理而直接返回success值。
在配置action 元素时,如果指定 method属性值,则该 Action 可以调用method属性中指定的方法,而不是默认的execute() 法。
(3 )result 元素
当调用Action 方法处理结束返回后,下一步就是使用result 元素来设置返回给浏览器的视图。配置 result 元素时常需指定name和type 两个属性。name属性对应从Action 方法返回的值, success 为其默认值。type 属性指定结果类型,默认的类型是 dispatcher,Struts2 支持的结果类型如表5.3 所示。
表5.3 Struts2 支持的结果类型
结果类型 说 明
dispatcher 将请求forward(转发)到指定的JSP 页面
redirect 将请求重定向到指定的视图资源
chain 处理Action 链
freemarker 指定使用Freemarker 模板作为视图
httpheader 控制特殊的HTTP 行为
redirect-action 直接跳转到其他Action
stream 向浏览器返回一个InputStream (一般用于文件下载)
velocity 指定使用velocity模板作为视图
xslt 用于XML/XSLT整合
plainText 显示某个页面的原始代码
读者需要注意的是dispatcher和redirect的区别,也就是转发和重定向的区别,重定向会丢失所有的请求参数,而且会丢失Action 的处理结果。
此处先介绍redirect 和redirect-action 这两种结果类型,其他一些常用类型会在后续章节进行介绍。
① redirect 类型
redirect 结果类型与dispatcher结果类型刚好是相反的,初学者在使用时容易将它们混淆。dispatcher结果类型表示将HTTP 请求转发到指定的JSP 资源,redirect 结果类型则是将请求重定向到JSP 资源,而重定向的结果则会丢失所有的请求参数和Action 的处理结果。
② redirect-action 类型
redirect-action 结果类型主要用于当一个Action 处理结束后,将请求重定向到另一个Action 。它和redirect 结果类型一样,会重新生成一个新请求,而且Action 处理结果及请求的所有参数都会丢失,只是redirect-action 结果类型生成的请求是一个Action ,而redirect结果类型生成的请求是一个JSP 资源。
【例5-2】 本例说明redirect-action 结果类型的用法。
(a )在Eclipse 创建一个Java Web 项目,将Struts 2 框架所需的支持库添加到WEB-
INF 目录下的lib 文件夹中,然后在 WEB-INF目录下添加web.xml 文件,并在其中注册过滤器和欢迎页面。web.xml 文件代码如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/
xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:
schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!--定义Filter-->
<filter>
<filter-name>struts2</filter-name> <!--指定Filter 的名字,不能为空-->
<!--指定Filter 的实现类,此处使用的是Struts 2 提供的过滤器类-->
<filter-class>org.apache.struts2.dispatcher.ng.filter.
StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!--定义Filter 所拦截的URL 地址-->
<filter-mapping>
<!--Filter的名字,该名字必须是filter 元素中已声明过的过滤器名字-->
<filter-name>struts2</filter-name>
<url-pattern>/
*
</url-pattern> <!--定义 Filter 负责拦截的URL 地址-->
</filter-mapping>
<!--欢迎页面-->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
(b )在src 目录下创建包com.action,在该包下创建LoginAction.java和UserAction.java文件,这两个文件的代码如下所示。
LoginAction.java代码如下:
package com.action;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private static final long serialVersionUID = 1L;
//重载execute()方法,返回SUCCESS
public String execute() throws Exception {
return SUCCESS;
}
//redirect()方法,返回ERROR
public String redirect() throws Exception {
return ERROR;
}
}
UserAction.java 代码如下:
package com.action;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
private static final long serialVersionUID = 1L;
//重载execute()方法,返回SUCCESS
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}
}
(c )在src 目录下创建struts.xml 文件,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--配置包default,该包继承了struts-default -->
<package name="default" extends="struts-default">
<!--配置名为login 的Action ,实现类为LoginAction -->
<action name="login" class="com.action.LoginAction">
<!--redirectAction返回类型 -->
<result type="redirectAction">
<param name="actionName">userLogin</param> <!--Action 名参数 ->
<param name="namespace">/user</param> <!-- 命名空间参数-->
</result>
<!--返回值为error,redirectAction 类型,重定向到名为error的Action-->
<result name="error" type="redirectAction">error</result>
</action>
<!--配置名为error的Action -->
<action name="error">
<result>/error.jsp</result>
</action>
</package>
<!--配置名为user 的包,命名空间为/user-->
<package name="user" extends="struts-default" namespace="/user">
<!-- 配置名为userLogin 的Action-->
<action name="userLogin" class="com.action.UserAction">
<result>/hello.jsp</result>
</action>
</package>
</struts>
(d )在WebContent目录下创建文件index.jsp ﹑hello.jsp 和error.jsp,核心代码如下所示。
index.jsp 文件核心代码如下:
<body>
<center>
<s:a action="login">login</s:a><br/>
<s:a action="login!redirect.action" >redirect</s:a>
</center>
</body>
hello.jsp 文件核心代码如下:
<body>
<center>
<h2>hello</h2>
</center>
</body>
error.jsp 文件核心代码如下:
<body>
<center>
<h2>error</h2>
</center>
</body>
在这个例子中,读者应该注意到redirect 结果类型的运用有两种方式:一是直接在<result>标签后添加Action 名称,二是运用<param> 标签的方式来指定Action 。这两种方式都可以达到同样的效果,可以根据需要选用。
(4 )include 元素
该元素用来在一个struts.xml 配置文件中包含其他的配置文件。默认情况下,当查找Action 时,Struts 2 框架只会加载struts.xml 配置文件,但是当系统规模增大到一定的程度时,系统中的Action 数量也会大大增加,这将会导致一个struts.xml 配置文件中包含大量的Action ,显然不方便开发者进行编辑。通过<include../> 标签,可以将 Action 以模块的方式来加以管理,即将存在相关性的Action 放到同一个xml 文件中,然后通过在struts.xml文件中配置<include../> 标签来将它们组合在一起。使用include 元素的struts.xml 文件片段如下所示:
<struts>
<include file="a.xml"/>
<include file="b.xml"/>
<include file="c.xml"/>
<include file="d.xml"/>
</struts>
需要注意的是,这些模块化的xml 文件也必须是标准的Struts 2 配置文件,即必须包含头信息以及根元素等。通常,Struts 2框架的所有配置文件都放在WEB-INF/classes路径下,由于struts.xml 文件中配置了<include../> 标签,则可以将其对应包含的文件信息加载进来。
(5 )global-results 元素
该元素配置包中的全局结果,其代码示例如下所示。在该代码示例中配置了一个全局结果,这个全局结果的作用范围为包下面所有 Action 。当一个 Action 处理用户请求后返回时,会首先在该 Action 本身的局部结果中进行搜索,如果局部结果中没有对应的结果,则会查找全局结果。
<struts>
<!--配置包default,命名空间为“/ ”-->
<package name="default" namespace="/" extends="struts-default">
<!--全局结果 -->
<glabal-results>
<result name=”success”>/SUCCESS.jsp</result>
</global-result>
<!--配置名为user 的Action -->
<action name="user" class="com.action.UserAction">
<result name="hello">/hello.jsp</result> <!--返回hello -->
</action>
</package>
</struts>
(6 )default-action-ref元素
该元素用来配置默认的Action ,即如果Struts 2找不到对应的Action 时,就会使用默认的Action 来处理用户请求。
<!--默认Action 为defaultaction-->
<default-action-ref name="defaultaction"/>
<action name="defaultaction" class="com.action.XXXAction">
<result ../>
…
</action>
在以上代码中,default-action-ref 元素仅有一个name 属性,该name 属性指向一个Action ,这个Action 将成为默认的Action 。