10级学员 庞丽课堂笔记
Struts2的Action处理用户请求结束后,返回一个普通字符串——逻辑视图名,必须在struts.xml文件中完成逻辑视图和物理视图资源的映射,才可以让系统转到实际的视图资源。
简单的说,结果是告诉struts2框架,当Action处理结果时,系统下一步做什么。当Action返回一个普通字符串时,系统下一步将做什么。
Struts2通过在struts.xml文件中使用<result…/>元素来配置结果。根据<result…/>元素所在位置的不同,struts2提供了两种结果:
(1) 局部结果:将<result…/>作为<action…/>元素的子元素配置。
(2) 全局结果:将<result…/>作为<global-result…/>元素的子元素配置。
一、 下面我们首先来介绍一下局部结果,局部结果是通过在<action../>元素中指定<result…/>元素来配置的,一个<action…/>元素可以有多个<result…/>元素。这表示一个Action可以对应多个结果。
最典型的<result…/>配置如下:
<action name="login" class="cn.csdn.hr.action.LoginAction" method="checkLogin"> <!-- 为success的逻辑视图配置Result,type属性指定结果类型 --> <result name="success" type="dispatcher"> <!-- 指定该逻辑视图对应的实际视图资源 --> <param name="location">./login.jsp</param> </result> </action>
对于上面使用了<param../>子元素配置结果的形式,其中<param../>元素的name属性可以有如下两个值:
(1) location:该参数指定了该逻辑视图对应的实际视图资源。
(2) parse:该参数指定是否允许在实际视图名字中使用OGNL表达式,该参数默认值为true。如果设置该参数值为false,则不允许在实际视图名中使用表达式。通常无需修改该属性值。因为通常无需指定parse参数的值。
除此之外,struts2还允许省略指定结果类型,即可简写成如下:
<action name="login" class="cn.csdn.hr.action.LoginAction" method="checkLogin"> <result>./login.jsp</result> </action>
二、struts2支持的处理结果类型
归纳一下来说,Struts2内建支持结果类型如下:
(1) chain结果类型:Action链式处理的结果类型。
(2) chart结果类型:用于整合JFreeChart的结果类型。
(3) dispatcher结果类型:用于FreeMarker整合的结果类型。
(4) httpheader结果类型:用于控制特殊的HTTP行为的结果类型。
(5) jasper结果类型:用于JasperReports整合的结果类型。
(6) jsf结果类型:用于与JSF整合的结果类型。
(7) redirect结果类型:用于直接跳转到其他URL的结果类型。
(8) redirect-action结果类型:用于制直接跳转到其他Action的结果类型。
(9) stream结果类型:用于向浏览器返回一个InputStream(一般用于文件下载)。
(10) tiles结果类型:用于与Tiles整合的结果类型。
(11) velocity结果类型:用于与Velicity整合的结果类型。
(12) xslt结果类型:用于与XML/XSLT整合的结果类型。
(13) plaintext结果类型:用于显示某个页面的原始代码的结果类型。
上面一共列出了14种类型,其中dispatcher结果类型是默认的类型,主要用于与JSP页面整合。
下面我将重点介绍dispatcher(默认值)、 redirect 、 redirectAction 、 plainText。常用的结果类型。
1、 plaintext结果类型
这个结果类型并不常用,因为它的作用太过局限:它主要用于显示实际视图资源的源代码。
以下是一个关于plaintext结果类型的小案例分析及其源代码以及显示效果:
对于如下简单的Action类:
public class LoginAction implements Action{ //用于封装请求参数的username属性 private String username; //username属性的setter和getter方法 public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } //处理用户请求的excute方法 public String execute() throws Exception { return SUCCESS; } }
上面的Action类并为真正处理用户请求,它只是简单地返回了一个success的逻辑视图。在struts.xml文件中配置该Action,如果采用如下配置片段:
<?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> <!-- package 包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action --> <package name="test" extends="struts-default" namespace="/"> <!-- 配置一个Action --> <action name="login" class="cn.csdn.hr.action.LoginAction"> <!-- 指定Result的类型为plaintext类型 --> <result type="plaintext"> <!-- 指定实际的视图资源 --> <param name="location">./welcome.jsp</param> <!-- 指定使用特定的编码集来处理页面代码 --> <param name="charSet">utf-8</param> </result> </action> </package> </struts>
Jsp代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> </head> <body> <s:property value="username"/> </body> </html>
如果将result的type指定为plaintext,那么将显示如下的效果:
这是将type类型指定为plaintext,显示的是视图资源的源代码。如果不指定类型,那么就是默认的类型dispatcher ,其默认类型,我输入的用户名是redarmy,点击提交按钮:显示效果如图:
2、 redirect结果类型:
(1)redirect结果类型与dispatcher结果类型相对,dispatcher结果类型是将请求Forward(转发)到指定的JSP资源;而redirect结果类型,是将请求Redirect(重定向)到指定的JSP视图资源。
(2)dispatcher结果类型与redirect结果类型的差别主要就是转发和重定向的差别;重定向会丢失所有的请求参数、请求属性——当然也丢失了Action的处理结果。
(3)使用redirect结果类型的效果是,系统将调用HttpServletResponse的sendRedirect(String)方法来重定向指定视图资源,这种重定向的效果就是重新产生一个请求,因此所有的请求参数、请求属性、Action实例和Action中的封装的属性全部丢失。
对于上面的应用,如果将struts.xml文件修改成如下形式;
<struts> <!-- package 包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action --> <package name="csdn" extends="struts-default" namespace="/"> <!-- 配置一个Action --> <action name="login" class="cn.csdn.hr.action.LoginAction"> <!-- 指定Result的类型为redirect类型 --> <result type="redirect">./welcome.jsp</result> </action> </package> </struts>
上面的Result使用了redirect的结果类型,意思是:当Action处理用户请求结束后,系统将重新生成一个请求,直接转入welcome.jsp中。
效果图如下:
3、 redirect-action结果类型
这种结果类型与redirect类型非常相似,一样是重新生成一个全新的请求。
下面使用redirect-action结果类型的配置的实例:
<struts> <!-- package 包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action --> <package name="csdn" extends="struts-default" namespace="/"> <!-- 配置一个Action --> <action name="login" class="cn.csdn.hr.action.LoginAction"> <!-- 指定Result的类型为plaintext类型 --> <result type="redirect-action"> <!-- 指定重定向的actionName --> <param name="actionName">aaa</param> <!-- 指定重定向的Action所在的命名空间 --> <param name="names">/secure</param> </result> </action> </package> <package name="csdn1" extends="struts-default" namespace="/"> <!-- 配置一个Action --> <action name="aaa" class="cn.csdn.hr.action.ChongAction"> <!-- 指定Result的类型为plaintext类型 --> <result>./aaa.jsp</result> <!--配置一个redirect-action结果类型的result,重定向同一个命名 空间的Action --> <result type="redirect-action" name="error">error</result> </action> <action name="error"> <result>error.jsp</result> </action> </package> </struts>
使用redirect-action结果类型时,系统将重新生成一个新请求,只是该请求的URL不是一个具体的视图资源,而是一个Action,因此前一个Action处理结果,请求参数、请求属性都会丢失。
三、动态结果
动态结果的意思是指配置结果时,指定实际视图资源时使用了表达式语法,通过这种语法可以允许Action处理完用户请求后,动态转入实际的视图资源。
(1) 前面介绍Action配置时,可以通过在Action的name属性中使用通配符,在class或method属性中使用表达式。通过这种方式,我们可以根据请求来动态决定Action的处理类,以及动态决定处理方法。除此之外,我们也可以在配置<result../>元素时使用表达式语法,从而允许根据请求动态决定实际资源。
看下面的配置片段:
<action name="login" class="cn.csdn.hr.action.LoginAction"> <result name="input">./input.jsp</result> <result>./success.jsp</result> </action>
当Action处理用户请求结束后,配置了两个结果:处理结果为input字符串时,系统将转到input.jsp页面:当处理结果为success字符串时,系统将转入success.jsp页面——这个视图资源时动态生成的。
四、请求参数决定结果
配置<result../>元素时,不仅可以使用${0}表达式形式来指定视图资源,还可以使用${属性名}的方式来指定视图资源。
下面我们通过一个案例还进一步了解它的使用:
(1) 首先定义出处理该请求的Action,它仅仅提供了一个属性来封装请求参数,并提供了一个参数才封装处理后的提示。下面是该Action类的代码。
import com.opensymphony.xwork2.Action; public class LoginAction implements Action{ //封装请求参数的target属性 private String target; //封装处理结果提示的tip属性 private String tip; //target属性和tip属性对应的getter和setter方法 public String getTarget() { return target; } public void setTarget(String target) { this.target = target; } public String getTip() { return tip; } public void setTip(String tip) { this.tip = tip; } //处理用户请求的excute方法 public String execute() throws Exception { setTip("恭喜您!您已成功转向!"); return SUCCESS; } }
第二步我们来在struts.xml文件中配置该Action,配置文件如下:
<struts> <!-- package 包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action --> <package name="csdn" extends="struts-default" namespace="/"> <!-- 配置一个Action --> <action name="login" class="cn.csdn.hr.action.LoginAction"> <result name="success">./${target}.jsp</result> </action> </package> </struts>
这个程序就会实现跳转。
五、全局结果
前面已经提到了,struts2的<result../>元素配置,也可以放在<global-results../>元素中配置,当在<global-results../>元素中配置<result../>元素时,该<result../>元素配置了一个全局结果,全局结果的作用范围是对所有的Action都有效。
struts.xml配置文件如下:
<struts> <!-- package 包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action --> <package name="csdn" extends="struts-default" namespace="/"> <!-- 定义全局结果 --> <global-results> <!-- 下面定义的结果对所有的Action都有效 --> <result name="success">../${target}.jsp</result> </global-results> <!-- 配置处理用户请求的Action --> <action name="login" class="cn.csdn.hr.action.LoginAction"/> </package> </struts>
上面的配置片段配置了一个Action,但在该Action内没有配置任何的结果——但这不会影响系统的运转,因为提供了一个名为success的全局结果,而这个全局结果的作用范围对所有的Action都有效。
如果一个Action里包含了与全局结果里同名的结果,则Action里的局部Action会覆盖全局Action。也就是说,当Action处理用户请求结束后,会首先在本Action里的局部结果里搜索逻辑视图对应的结果。只有在Action里的局部结果里找不到逻辑视图对应的结果,才会到全局结果里搜索。