Action的结果值传递类型

一个result代表了一个可能的输出。当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出。

在com.opensymphony.xwork2.Action接口中定义了一组标准的结果代码,可供开发人员使用,当然了只有我们的action继承ActionSupport这个类才可以使用下面的结果代码,如下所示:

public interface Action
{
    public static final String SUCCESS = “success”;
    public static final String NONE = “none”;
    public static final String ERROR = “error”;
    public static final String INPUT = “input”;
    public static final String LOGIN = “login”;
}

其中Struts2应用在运行过程中若发现addFieldError()中有信息或者类型转换失败或着输入校验失败等情况那么它会自动跳转到name为input的<result/>,然后转到INPUT所对应的页面:

若JSP页面中表单是用普通<form>编写的,发生错误而返回该页面时,则原数据将消失

若JSP页面中表单是用<s:form/>编写的,发生错误而返回该页面时,则原数据仍存在

若没有提供name值为input的<result/>,那么发生错误时,将直接在浏览器中提示404错误

除了这些预定义的结果码外,开发人员也可以定义其它的结果码来满足自身应用程序的需要。

Result配置由两部分组成:一部分是result映射,另一部分是result类型。

一、配置 result映射

在result映射的配置中,在指定实际资源的位置时,可以使用绝对路径,也可以使用相对路径。绝对路径以斜杠(/)开头,相对于当前的Web应用程序的上下文路径;相对路径不以斜杠(/)开头,相对于当前执行的action的路径,也就是namespace指定的路径。

例如:

<package name="default" extends="struts-default" namespace="/admin">
    <action name="login" class="com.ibm.LoginAction">
            <result>success.jsp</result>
            <result name="error">/error.jsp</result>
    </action>
</package>

如果当前Web应用程序的上下文路径是/Shop,那么请求/Shop/admin/login.action,执行成功后,转向的页面路径为:/Shop/admin/success.jsp;执行失败后,转向的页面路径为/Shop/error.jsp

二、result结果类型详解

type 所有类型 :(在struts2-core.jar/struts-default.xml中可以找到)

Type 类型值 作用说明 对应类
chain 用来处理Action 链 com.opensymphony.xwork2.ActionChainResult
dispatcher(默认值) 用来转向页面,通常处理 JSP org.apache.struts2.dispatcher.ServletDispatcherResult
redirect 重定向到一个URL org.apache.struts2.dispatcher.ServletRedirectResult
redirectAction 重定向到一个 Action org.apache.struts2.dispatcher.ServletActionRedirectResult
plainText 显示源文件内容,如文件源码 org.apache.struts2.dispatcher.PlainTextResult
freemarker 处理 FreeMarker 模板 org.apache.struts2.views.freemarker.FreemarkerResult
httpheader 控制特殊 http 行为的结果类型 org.apache.struts2.dispatcher.HttpHeaderResult
stream 向浏览器发送 InputSream 对象,通常用来处理文件下载,还可用于返回 AJAX 数据。 org.apache.struts2.dispatcher.StreamResult
velocity 处理 Velocity 模板 org.apache.struts2.dispatcher.VelocityResult
xslt 处理 XML/XLST 模板 org.apache.struts2.views.xslt.XSLTResult

1、dispatcher结果类型

Struts2在后台使用Servlet API的RequestDispatcher来转发请求,因此在用户的整个请求/响应过程中,目标Servlet/JSP接收到的request/response对象,与最初的Servlet/JSP相同。

Dispatcher结果类型的实现是org.apache.struts2.dispatcher.ServletDispatcherResult,该类的二个属性(property):location和parse,这两个属性可以通过struts.xml配置文件中的result元素的param子元素来设置。param元素的name属性指定结果类型实现类的属性名,param元素的内容是属性的值。例如:

<result name=“success”  type=“dispatcher”>
    <param name=“location” >/success.jsp</param>
    <param name=“parse” >true</param>
</result>

说明:

A、location参数用于指定action执行完毕后要转向的目标资源,parse属性是一个布尔类型的值,如果为true,则解析location参数中的OGNL表达式;如果为false,则不解析。parse属性的默认值就是true.

location参数是默认的参数,在所有的Result实现类中,都定义了一个字符串类型的DEFAULT_PARAM静态常量,专门用于指定默认的参数名。

DEFAULT_PARAM常量的定义:public static final String

DEFAULT_PARAM=“location”;

B、在设置location参数时,可以在参数值中使用OGNL表达式。

<action name=“viewNews” class=“com.ibm.ViewNewsAction”
    <result name=“success”  type=“dispatcher”>
        <!--如果参数是中文:请参看最底部例子-->
        <param name=“location” >/viewNews.jsp?id=${id}</param>
        <param name=“parse” >true</param>
    </result>
</action>

考虑到默认值的使用(dispatcher和location都是默认值),上述可以简化为:

<action name=“viewNews” class=“com.ibm.ViewNewsAction”>
    <result name=“success” >viewNews.jsp?id=${id}</result>
</action>

2、redirect结果类型(重定向到一个Url,也可以是Action或一个页面)

Redirect结果类型在后台使用HttpServletResponse的sendRedirect方法将请求重定向到指定的URL,它的实现类是org.apache.struts2.dispatcher.ServletRedirectResult.该类同样有二个属性(property):location和parse,在使用redirect结果类型的场景中,用户要完成一次与服务器之间的交互,浏览器需要完成两次请求,因此第一次请求中的数据在第二次请求中是不可用的,这意味在目标资源中是不能访问action实例、action错误以及错误等。

如果有某些数据需要在目标资源中访问:

i、一种方式是将数据保存到Session中

ii、另一种方式是通过请求参数来传递数据

示例(1)、

<result name="success" type="redirect">  
    <param name="location">foo.jsp</param>
    <param name="parse">false</param><!--不解析OGNL-->
</result>

示例(2)、

<package name="passingRequestParameters"extends="struts-default"namespace="/passingRequestParameters">  
<-- Passparameters (reportType, width and height),重定向到Url并且传参 ,如果参数是中文:请参看最底部例子-->  
<!--  
 The redirect-action url generated will be : 
/genReport/generateReport.jsp?reportType=pie&width=100&height=100  
-->  

   <actionname="gatherReportInfo" class="...">  

      <resultname="showReportResult" type="redirect">  

         <param name="location">generateReport.jsp</param>  

         <param name="namespace">/genReport</param>  

         <param name="reportType">pie</param>  

         <param name="width">100</param> 

         <param name="height">100</param> 

     </result>  

  </action>  

</package> 

3、redirectAction结果类型(重定向到一个Action)

常用于防止表单重复提交,比方说在增加完用户之后要显示列表
redirectAction结果类型的实现类是org.apache.struts2.dispatcher.ServletActionRedirectResult,该类是ServletRedirectResult的子类,因此我们也就可以判断出redirectAction结果类型和redirect结果类型的后台工作原理是一样的,即都是利用HttpServletResponse的sendRedirect方法将请求重定向到指定的URL。

示例、

<package name="public"extends="struts-default">  
    <action name="login"class="...">  
        <!--Redirect to another namespace 重定向到不同命名空间下的    action --> 
        <result type="redirectAction">  
           <param name="actionName">dashboard</param> 
           <param name="namespace">/secure</param> 
        </result> 
    </action> 
</package> 



<package name="secure"extends="struts-default" namespace="/secure">  
<-- Redirectto an action in the same namespace,重定向到同一命名空间下的action -->
   
    <action name="dashboard" class="...">  
        <result>dashboard.jsp</result> 
        <result name="error"type="redirectAction">error</result> 
    </action> 
    
    <action name="error" class="...">  
        <result>error.jsp</result>
    </action> 
</package> 



<package name="passingRequestParameters"extends="struts-default"namespace="/passingRequestParameters">  
<-- Passparameters (reportType, width and height),重定向到Action并且传参,如果参数是中文:请参看最底部例子 --> 
<!--  
TheredirectAction url generated will be :   
/genReport/generateReport.action?reportType=pie&width=100&height=100 
--> 
    <action name="gatherReportInfo" class="...">  
        <result name="showReportResult" type="redirectAction">  
            <param name="actionName">generateReport</param> 
            <param name="namespace">/genReport</param> 
            <param name="reportType">pie</param> 
            <param name="width">100</param>
            <param name="height">100</param>
            <param name="empty"></param>
            <param name="supressEmptyParameters">true</param> 
        </result> 
    </action> 
</package>

4、链接类型 result:chain(从一个Action转发到另一个Action)

chain结果类型有4个属性,分别是:


actionName (default) - the name of the action that will be chained to

namespace - used to determine which namespace the Action is in that we're chaining. If namespace is null, this defaults to the current namespace

method - used to specify another method on target action to be invoked. If null, this defaults to execute method

skipActions - (optional) the list of comma separated action names for the actions that could be chained to


这个Result使用ActionMapperFactory提供的ActionMapper来重定位浏览器的URL来调用指定的action和(可选的)namespace. 这个Result比ServletRedirectResult要好.因为你不需要把URL编码成xwork.xml中配置的ActionMapper提供的模式. 这就是说你可以在任意点上改变URL模式而不会影响你的应用程序.

redirctAction在转发时无法携带原有的参数,而使用chain类型则直接将参数等信息传递到下一个action

示例、

<package name="public"extends="struts-default">  
<!-- Chain creatAccount to login, using the default parameter ,链接到同一命名空间下的Action,--> 
    <action name="createAccount" class="...">  
        <result type="chain">login</result>
    </action> 
    <action name="login" class="...">  
    <!--Chain to another namespace --> 
        <result type="chain">  
            <param name="actionName">dashboard</param> 
            <param name="namespace">/secure</param> 
        </result> 
    </action> 
</package> 

首先是 删除商品的控制器所对应的xml配置文件如下

<!-- This action 负责将用户不需的商品从购物车删除 -->  
<action  name="deletefromcart" class="eshop.action.DeletefromCart">  
    <interceptor-ref name="completeStack"></interceptor-ref>  
        <result name="success" type="chain">displaycart</result>  
    <result name="error" >error.html</result>  
</action>  

删除成功后,其中用type=chain的拦截器,指定让其去执行displaycart的控制器,

<action name="displaycart" class="eshop.action.DisplayCart">  
    <interceptor-ref name="completeStack"></interceptor-ref>  
    <result name="success" type="velocity>ShoppingCart.vm</result>  
    <result name="error" >error.html</result>  
</action>  

而这个displaycart的控制器其实就是刷新显示了当前的购物车了

5、HttpHeader Result:HttpHeader(用来控制特殊的Http行为)

httpheader结果类型很少使用到,它实际上是返回一个HTTP响应的头信息

示例:

<result name="success"type="httpheader">  
    <paramname="status">204</param>
    <paramname="headers.a">a custom header value</param>      <paramname="headers.b">another custom header value</param> 
</result> 
<result name="proxyRequired"type="httpheader">  
    <paramname="error">305</param>
    <paramname="errorMessage">this action must be accessed through aprozy</param> 
</result> 

6、Stream Result(向浏览器发送InputSream对象,通常用来处理文件下载)

<result name="success"type="stream">  
    <param name="contentType">image/jpeg</param> 
    <param name="inputName">imageStream</param> 
    <param name="contentDisposition">attachment;filename="document.pdf"</param>
    <param name="bufferSize">1024</param> 
</result>

7、PlainText Result(显示原始文件内容,例如文件源代码)

<action name="displayJspRawContent"> 
    <result type="plaintext">/myJspFile.jsp</result> 
</action>  
<action name="displayJspRawContent"> 
    <result type="plaintext">  
        <param name="location">/myJspFile.jsp</param> 
        <param name="charSet">UTF-8</param>
    </result> 
</action> 
若仅设置type="plainText"的话,页面中显示中文时会乱码,这时就可以借助它的charSet属性以解决中文显示时的乱码问题,如果不设置charSet属性,反而去配置struts.i18n.encoding全局属性,是不能解决问题的
设置charSet属性的目的就是让JSP页面的编码与明文显示时的编码一致

8、Velocity Result(处理Velocity模板)

<result name="success"type="velocity">  
    <paramname="location">foo.vm</param> 
</result> 

9、XLS Result(处理XML/XLST模板)

<result name="success" type="xslt">  
    <paramname="location">foo.xslt</param> 
    <paramname="matchingPattern">^/result/[^/*]$</param> 
    <paramname="excludingPattern">.*(hugeCollection).*</param> 
</result> 

10、 FreeMarkerResult (处理FreeMarker模板)

<result name="success"type="freemarker">foo.ftl</result>

附、另外第三方的Result类型还包括JasperReportsPlugin,专门用来处理JasperReport类型的报表输出。

<%@ tagliburi="http://tiles.apache.org/tags-tiles" prefix="tiles"%> 
<%@ taglib prefix="s"uri="/struts-tags" %> 
<%-- Show usage; Used in Header --%> 
<tiles:importAttribute name="title"scope="request"/>  
<html> 
   <head><title><tiles:getAsStringname="title"/></title></head>  
<body> 
   <tiles:insertAttribute name="header"/>  
      <pid="body">  
        <tiles:insertAttributename="body"/>  
    </p> 
    <p>Noticethat this is a layout made in JSP</p>
</body> 
</html>

注意!!!!.传递中文

记住永远不要在浏览器的地址栏中传递中文。在传递中文前先进行编码

A.action中

public class User extends ActionSupport{
 private String username;
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 @Override
 public String execute() throws Exception {
  // TODO Auto-generated method stub
  username=URLEncoder.encode("郭蕾","utf-8");//先进行编码
  System.out.println(username);
  return "redirect";
 }
}

B.struts.xml中

<action name="redirect" class="action.User">
     <result type="redirect" name="redirect">
     /redirect.jsp?username=${username}//如果要传递两个参数,中间用&amp;代替& </result>
</action>

在这里使用了类似于el表达式的方式传值,${username}其中username为action中定义的

C.redirect.jsp中

<body>
重定向
    <%String s=request.getParameter("username");
    s=new String(s.getBytes("iso8859-1"),"utf-8");
    s=URLDecoder.decode(s,"utf-8");
    out.println(s);
    %>
</body>

重定向中传递中文先进行编码,在jsp页面中先接受参数,然后对其进行字节分解,然后进行解码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • 概述 Struts就是基于mvc模式的框架!(struts其实也是servlet封装,提高开发效率!) Strut...
    奋斗的老王阅读 2,902评论 0 51
  • 详谈 Struts2 的核心概念 本文将深入探讨Struts2 的核心概念,首先介绍的是Struts2 的体系结构...
    可爱傻妞是我的爱阅读 1,101评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 1,一个完整的Java Web所涉及的内容包括:(1)Java Bean组件 (2)EJB组件 (3)自定义的JS...
    Mick_小聪阅读 984评论 0 1
  • 概述 什么是Struts2的框架Struts2是Struts1的下一代产品,是在 struts1和WebWork的...
    inke阅读 2,225评论 0 50