Struts2中 Result类型配置详解

来源:互联网 发布:华山派 知乎 编辑:程序博客网 时间:2024/06/06 03:46
 一个result代表了一个可能的输出。当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出。
com.opensymphony.xwork2.Action接口中定义了一组标准的结果代码,可供开发人员使用,当然了只有我们的action继承ActionSupport这个类才可以使用下面的结果代码,如下所示:
public interface Action
{
    publicstatic final String SUCCESS = “success”;
    publicstatic final String NONE = “none”;
    publicstatic final String ERROR = “error”;
    publicstatic final String INPUT = “input”;
    publicstatic 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>
         <resultname="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元素的内容是属性的值。例如:
  <resultname=“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 StringDEFAULT_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" 
            <paramname="location">foo.jsp</param>
            <paramname="parse">false</param><!--不解析OGNL--
>
         </result>
示例(2)、
   <packagename="passingRequestParameters"extends="struts-default"namespace="/passingRequestParameters">  

   <-- Passparameters (reportType, widthand 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">  

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

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

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

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

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

    </result>  


 </action>  

</package> 

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

   <actionname="login"class="...">  

       <!--Redirect to anothernamespace重定向到不同命名空间下的   action --> 
       <resulttype="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 samenamespace,重定向到同一命名空间下的action -->

   <action name="dashboard"class="...">  

      <result>dashboard.jsp</result> 

       <resultname="error"type="redirectAction">error</result> 

  </action> 

    <action name="error"class="...">  

      <result>error.jsp</result>

   </action> 
</package> 

 

<packagename="passingRequestParameters"extends="struts-default"namespace="/passingRequestParameters">  

  <-- Passparameters (reportType, width andheight),重定向到Action并且传参
如果参数是中文:请参看最底部例子--> 

  <!--  
   TheredirectAction urlgenerated will be:   
/genReport/generateReport.action?reportType=pie&width=100&height=100 
   --> 

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

     <resultname="showReportResult"type="redirectAction" 

        <paramname="actionName">generateReport</param> 

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

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

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

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

        <paramname="empty"></param>

        <paramname="supressEmptyParameters">true</param> 

    </result> 


 </action> 

</package>

4、链接类型 result:chain(从一个Action转发到另一个Action
  chain结果类型有4个属性,分别是:

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

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

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

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


示例、
 <packagename="public"extends="struts-default">  

    <!-- ChaincreatAccount to login, using the default parameter,链接到同一命名空间下的Action,--> 

   <action name="createAccount"class="...">  

       <resulttype="chain">login</result>

  </action> 

   <actionname="login"class="...">  

       <!--Chain to anothernamespace --> 

       <resulttype="chain">  

          <paramname="actionName">dashboard</param> 

          <paramname="namespace">/secure</param> 

      </result> 


  </action> 

</package> 

<package name="secure"extends="struts-default"namespace="/secure">  

   <actionname="dashboard"class="...">  

      <result>dashboard.jsp</result> 

  </action> 

</package>
5、HttpHeaderResult:
HttpHeader(用来控制特殊的Http行为)
  httpheader结果类型很少使用到,它实际上是返回一个HTTP响应的头信息
 示例:<resultname="success"type="httpheader">  
    <paramname="status">204</param>
    <paramname="headers.a">a customheadervalue</param>     <paramname="headers.b">another customheadervalue</param> 
   </result> 

<resultname="proxyRequired"type="httpheader">  
  <paramname="error">305</param>
  <paramname="errorMessage">this actionmust be accessed throughaprozy</param> 

</result> 
6、StreamResult(向浏览器发送InputSream对象,通常用来处理文件下载)
  <resultname="success"type="stream">  

  <paramname="contentType">image/jpeg</param> 

  <paramname="inputName">imageStream</param> 

  <paramname="contentDisposition">attachment;filename="document.pdf"</param>  

  <paramname="bufferSize">1024</param> 
</result>
7、PlainTextResult(
显示原始文件内容,例如文件源代码)
  <actionname="displayJspRawContent"> 

  <resulttype="plaintext">/myJspFile.jsp</result> 
 </action>  

<actionname="displayJspRawContent"> 

  <resulttype="plaintext">  

    <paramname="location">/myJspFile.jsp</param> 

    <paramname="charSet">UTF-8</param>

 </result> 
</action> 
  若仅设置type="plainText"的话,页面中显示中文时会乱码,这时就可以借助它的charSet属性以解决中文显示时的乱码问题,如果不设置charSet属性,反而去配置struts.i18n.encoding全局属性,是不能解决问题的
设置charSet属性的目的就是让JSP页面的编码与明文显示时的编码一致
8、VelocityResult(处理Velocity模板)
  <resultname="success"type="velocity">  
   <paramname="location">foo.vm</param> 
 </result> 

9、XLSResult(处理XML/XLST模板)
  <resultname="success"type="xslt">  

 <paramname="location">foo.xslt</param> 

 <paramname="matchingPattern">^/result/[^/*]$</param> 

 <paramname="excludingPattern">.*(hugeCollection).*</param> 
</result> 
10、FreeMarkerResult (处理FreeMarker模板)
 
<resultname="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:importAttributename="title"scope="request"/>  

<html> 

  <head><title><tiles:getAsStringname="title"/></title></head>  

<body> 

  <tiles:insertAttributename="header"/>  

     <pid="body">  

       <tiles:insertAttributename="body"/>  

   </p> 

   <p>Noticethat this is a layout madein JSP</p>

</body> 

</html>



注意!!!!.传递中文

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


A.action中

public class User extendsActionSupport{
 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 methodstub
  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>
   重定向
   <%Strings=request.getParameter("username");
    s=newString(s.getBytes("iso8859-1"),"utf-8");
   s=URLDecoder.decode(s,"utf-8");
   out.println(s);
   %>
  </body>


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



使用Struts2对JSON的扩展

    要使用这个扩展功能肯定需要添加支持包。经过本人的调试,这里有两种选择:

1.   xwork-core-2.1.6.jar和struts2-json-plugin-2.1.8.jar。如果你想使用struts2-json-plugin-2.1.8.jar这种支持方式,你的xwork-core-*.jar不能选择2.2.1及以上版本,因为xwork-core-*.jar的2.2.1及以上版本中没有了org.apache.commons.lang等包。启动tomcat的时候会出现:java.lang.NoClassDefFoundError: org.apache.commons.lang.xwork.StringUtils。

 

2.   xwork-2.1.2.jar和jsonplugin-0.34.jar。如果想用jsonplugin-0.34.jar这种支持方式,那需要切换你的xwork-core-*.jar为xwork-2.1.2.jar。因为jsonplugin-0.34.jar需要com.opensymphony.xwork2.util.TextUtils

这个类的支持。而xwork-core-*.jar的2.2.1以上版本均为找到该类,且在xwork-core-2.1.6.jar中也没有该类。

 

      最后说一句,还因为用原始构建方式而不停蹚雷,确实不值得,真心累。使用Maven等自动化构件方式,会在很大程度上避免依赖包间的版本差异的bug。第三节的“struts2零配置”中会使用maven的构件方式。

 

   编写接口代码

   该类中json()方法就是普通Struts2的方法。在这里没有看到任何JSON格式的字符串,因为我们将要把这项工作交给扩展去完成。在没有任何设定的情况下,改类下的所有getter方法的返回值将被包含在返回给客户端的JSON字符串中。要剔除不需要包含的属性,在类结构结构中需要在getter方法上使用@JSON(serialize=false)进行注解,当然在不影响其他业务的时候也可以直接去掉这个getter方法。所以本例中的返回结果是将dataMap对象转换成的JSON格式的字符串。

Java代码  收藏代码
  1. package json;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import org.apache.struts2.json.annotations.JSON;  
  7. import com.opensymphony.xwork2.ActionSupport;  
  8.   
  9. /** 
  10.  * JSON测试 
  11.  *  
  12.  * @author Watson Xu 
  13.  * @date 2012-8-4 下午06:21:01 
  14.  */  
  15. public class JsonAction extends ActionSupport{  
  16.     private static final long serialVersionUID = 1L;  
  17.       
  18.     private Map<String,Object> dataMap;  
  19.     private String key = "Just see see";  
  20.       
  21.     public String json() {  
  22.         // dataMap中的数据将会被Struts2转换成JSON字符串,所以这里要先清空其中的数据  
  23.         dataMap = new HashMap<String, Object>();  
  24.         User user = new User();  
  25.         user.setName("张三");  
  26.         user.setPassword("123");  
  27.         dataMap.put("user", user);  
  28.         // 放入一个是否操作成功的标识  
  29.         dataMap.put("success"true);  
  30.         // 返回结果  
  31.         return SUCCESS;  
  32.     }  
  33.   
  34.     public Map<String, Object> getDataMap() {  
  35.         return dataMap;  
  36.     }  
  37.   
  38.     //设置key属性不作为json的内容返回  
  39.     @JSON(serialize=false)  
  40.     public String getKey() {  
  41.         return key;  
  42.     }  
  43.       
  44. }  
 

    配置aciton

    在配置中,首先需要action所在的package继承了json-default,或者继承的父包继承了json-default。这配置action的返回类型的type为json,并且可以配置其序列化的属性等一些类参数

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5. <struts>   
  6.     <package name="json" extends="struts-default,json-default" >  
  7.         <action name="json" class="json.JsonAction" method="json">  
  8.             <result type="json">  
  9.                 <!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->  
  10.                 <param name="root">dataMap</param>  
  11.             </result>  
  12.         </action>  
  13.     </package>  
  14. </struts> 



0 0
原创粉丝点击