Struts2 ResultType结果类型配置详解

本节主要介绍 Action 的几种 Result type 类型,重点介绍了 dispatcher 和 redirect 结果类型。

配置Result

在 struts.xml 文件中,<result> 元素用于配置 Result 逻辑视图与物理视图之间的映射关系,它有两个可选属性 name 和 type。其中,name 属性用于指定逻辑视图的名称,默认值为 success;type 属性用于指定返回的视图资源的类型,不同的类型代表不同的结果输出,它的默认值是 dispatcher。

struts.xml 文件中的 <result> 元素配置示例代码如下所示:
<action name="loginAction" class="com.mengma.action.LoginAction">
    <result name="success" type="dispatcher">
        <param name="location">/success.jsp</param>
    </result>
</action>
上述代码为 Action 配置了一个 name 为 success 的 Result 映射,该映射的值可以是 JSP 页面,也可以是一个 Action 的 name 值;这里使用 param 子元素为其指定了 Result 映射对应的物理视图资源为 success.jsp。

<param> 子元素的 name 属性有两个值,分别如下。
  • location:指定该逻辑视图所对应的实际视图资源。
  • parse:指定在逻辑视图资源名称中是否可以使用 OGNL(对象图导航语言)表达式。默认值为 true,表示可以使用,如果设为 false,则表示不支持。

其实,上述配置代码还可以简化为如下形式:
<action name="loginAction" class="com.mengma.action.LoginAction">
    <result>/success.jsp</result>
</action>
需要注意的是,在 Result 配置中指定实际资源位置时,可以使用绝对路径,也可以使用相对路径。
  • 绝对路径以斜杠“/”开头,例如<result>/success.jsp</result>,相当于当前 Web 应用程序的上下文路径。
  • 相对路径不以斜杠“/”开头,例如 <result>success.jsp</result>,相当于当前执行的 Action 路径。

预定义的结果类型

在使用 Struts2 框架编写项目时,当框架调用 Action 对请求进行处理后,就要向用户呈现一个结果视图。在 Struts2 中,预定义了多种 ResultType(结果类型)展示结果视图。

一个结果类型就是实现了 com.opensymphony.xwork2.Result 接口的类,Struts2 把内置的 <result-type> 都放在 struts-default 包中,struts-default 包就是配置包的父包,这个包定义在 struts2-core-2.3.24.jar 包的根目录下的 struts-default.xml 文件中,在该文件中可以找到相关的 <result-type> 的定义,其代码如下所示:
<result-types>
    <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
    <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
    <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
    <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
    <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
    <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
    <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
    <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
    <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
    <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
    <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>
在上述代码中,每个 <result-type> 元素都是一种视图技术或者跳转方式的封装,其中 name 属性指出在 <result> 元素中如何引用这种视图技术或者跳转方式,它对应着 <result> 元素的 type 属性。class 属性表示这种结果类型的对应类。

Struts2 中预定义的 ResultType 说明如表 1 所示。
表 1 Struts2中预定义的ResultType
属     性 说     明
chain 用于处理 Action 链,被跳转的 Action 中仍能获取上个页面的值,如 request 信息
dispatcher 用于转向页面,通常处理 JSP,是默认的结果类型
freemarker 用于整合 FreeMarker 模板结果类型
httpheader 用于处理特殊的 HTTP 行为结果类型
redirect 重定向到一个 URL,被跳转的页面中丢失传递的信息
redirectAction 重定向到一个 Action,跳转的页面中丢失传递的信息
stream 向浏览器发送 InputStream 对象,通常用于处理文件下载,还可用于 Ajax 数据
velocity 用于整合 Velocity 模板结果类型
xslt 用于整合 XML/XSLT 结果类型
plainText 显示原始文件内容,如文件源代码
postback 使当前请求参数以表单形式提交
表 1 列举了 Struts2 中预定义的全部 11 种结果类型,其中 dispatcher 是默认的结果类型,主要用于与 JSP 整合。在这全部 11 种结果类型中,dispatcher 和 redirect 是比较常用的结果类型。

需要注意的是,redirect 与 dispatcher 结果类型非常相似,所不同的是 dispatcher 结果类型是将请求转发到 JSP 视图资源,而 redirect 结果类型是将请求重定向到 JSP 视图资源。如果重定向了请求,那么将丢失所有参数,包括 Action 的处理结果。

dispatcher结果类型

dispatcher 是 Struts2 的默认结果类型,它用于表示转发到指定结果资源。

由于 Struts2 在后台使用 RequestDispatcher 的 forward() 方法转发请求,所以在用户的整个请求/响应过程中,保持的是同一个请求对象,即目标 JSP/Servlet 接收到的请求/响应对象与最初的 JSP/Servlet 的请求/响应对象相同。

dispatcher 结果类型的对应类是 org.apache.struts2.dispatcher.ServletDispatcherResult,该类有 location 和 parse 两个属性,可以通过 struts.xml 配置文件中的 <result> 元素的 <param> 子元素设置,代码如下所示:
<result name="success" type="dispatcher">
    <param name="location">/success.jsp</param>
    <param name="parse">true</param>
</result>
在上述代码中,location 参数用于指定 Action 执行完毕后要转向的目标资源;parse 参数是一个布尔类型的值,默认是 true,表示解析 location 参数中的 OGNL 表达式,如果为 false,则不解析。

redirect结果类型

redirect 结果类型用于重定向到指定的结果资源,该资源可以是 JSP 文件,也可以是 Action 类。使用 redirect 结果类型时,系统将调用 HttpServletResponse 的 sendRedirect() 方法将请求重定向到指定的 URL。

redirect 结果类型的对应类是 org.apache.struts2.dispatcher.ServletRedirectResult。在使用 redirect 时,用户要完成一次和服务器之间的交互,浏览器需要发送两次请求,请求过程如图 1 所示。
Redirect结果类型的工作原理
图 1 Redirect 结果类型的工作原理
使用 redirect 结果类型的工作过程如下。

1)浏览器发出一个请求,Struts2框架调用对应的Action实例对请求进行处理。

2)Action返回success结果字符串,Struts2框架根据这个结果选择对应的结果类型,这里使用的是redirect结果类型。

3)ServletRedirectResult在内部使用HttpServletResponse的sendRedirect()方法将请求重新定向到目标资源。

4)浏览器重新发起一个针对目标资源的新请求。

5)目标资源作为响应呈现给用户。

下面通过修改《Action访问Servlet API》教程中的登录案例,演示如何使用 redirect 结果类型。修改配置文件 struts.xml 中 LoginAction 的配置信息,具体如下所示:
<action name="login" class="com.mengma.action.LoginAction">
    <result name="success" type="redirect">/success.jsp</result>
    <result name="error" type="dispatcher">/error.jsp</result>
</action>
在上述配置代码中,将成功登录的结果类型设置为 redirect,它表示当 Action 处理请求后会重新生成一个请求。将错误的结果类型设置为 dispatcher,这也是结果类型的默认值。

启动项目,在浏览器的地址栏中输入地址 http://localhost:8080/struts2Demo02/login.jsp,成功访问页面后,分别输入用户名“admin”和密码“123456”,单击【登录】按钮后,如果用户名和密码正确,将重定向到 success.jsp 页面,请求地址栏中显示的是 success.jsp,而不是 login.action,如图 2 所示。

重定向页面的效果
图 2  重定向页面的效果

从图 2 中可以看出,地址栏中显示的是 success.jsp。由于使用 redirect 重定向到其他资源时,将重新产生一个请求,并且原来的请求内容和参数将全部丢失,所以页面中的用户名和密码没有显示。

当用户名和密码错误时,使用的是 dispatcher 结果类型,此时页面将跳转到 error.jsp,由于是请求转发行为,所以地址栏中显示的还是 login 的请求信息,但页面中显示的是 error.jsp 中的内容,如图 3 所示。

转发页面的效果
图 3  转发页面的效果