Struts中,所有动作都需要配置结果,其实结果也即是表明动作处理的状态。Struts内置了十种结果类型可以供我们使用,如果这还不能满足你的要求,你还可以自定制Result。这一切的一切,已经能满足大多数项目的需求了。
Struts内置的结果类型
在struts的核心包struts.core下你可以看到一个struts-default.xml文件,在这个文件里面,声明了Result的类型如下:
<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-types>
在我们配置result元素的时候,其实该元素的type属性就是result-type中的name属性。
struts.xml配置文件中的一些默认值
在往下讲的同时,先了解一下struts.xml中怎样去配置一个动作,具体的一个例子如下:
<action name="input" class="com.daniel.action.user.InputAction">
<result name="input">/jsp/AddUser.jsp</result>
<result name="success">/jsp/AddUser.jsp</result>
</action>
在这里,我只讲result元素的配置会存在默认值的地方,一共有两个。一个是name属性,这个属性在你不写的时候,默认为name="success";另外一个是type属性,这个属性在你不写的时候,默认为type="dispatch"。
结果类型的逐一解析
1.type="chain"稍微接触 过java web的开发人员都知道,存在一种Filter的技术,Filter过滤请求并对请求进行处理,请求也可以通过好几个Filter顺序地进行处理,Struts的动作也存在这种类似的处理,即先把请求递交给A动作,A动作处理完毕之后又递交到B动作,如此直至请求递交给最后一个动作处理完成。当type="chain"时,需要提供以下的一些参数:
- actionName,下一动作的name属性值,这个值时肯定要配置的
- namespace,下一动作的namespace属性值,如果不配置,就是当前动作所在的namespace
- method,下一动作执行的方法,不配置的话就调用execute
- skipActions
动作链在很多书籍里面对它的描述是不推荐使用的,原因是它可能会使你的动作们乱成一团麻,具体使用还是不使用,还得看项目来拿捏。
2.type="dispatcher"这是result中type属性的默认值,意思是将控制权转交给页面。这种结果类型可以配置以下的两个参数:
- location,动作执行完毕之后,跳转到的url,一般是jsp页面
- parse,默认值为true,将该动作转换成为OGNL表达式,即压入OGNL的Object Stack栈中,选择为false,就不会将动作转换成OGNL表达式
3.type="freemaker"
当视图层技术选用freemaker模板时配置
4.type="httpheader"用来设置http头信息,比如404,403之类的,一般我会这么配置
<package name="user" namespace="/jsp" extends="struts-default">
<default-action-ref name="default"></default-action-ref>
<action name="default">
<result name="success" type="httpheader">404</result>
</action>
</package>
因为在使用了Struts后,如果你访问一个没有被配置的动作,那么是会返回一个带有“No Mapping for Acionxxx”之类的页面,而且还会抛出一个异常。上述配置可以在你访问/jsp/action的时候,即使访问到/jsp命名空间下不存在的动作,也不会抛出异常,而且不再显示默认的“No Mapping for Acionxxx”之类的页面,而是返回一个httpheader,404来告诉用户该资源不存在。
5.type="redirect"
页面重定向,但是这个重定向是客户端重定向。它的效果等效于response.sendRedirect()。客户端的重定向问题,就要考虑request对象的有效性了。而且,重要的一点是,当你使用了这个结果类型,OGNL context中的Object Stack不会把动作压栈。如下:
@SuppressWarnings("serial")
public class RedirectAction extends ActionSupport {
private String name = "123";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return super.execute();
}
}
struts.xml文件配置动作如下:
<action name="redirect" class="com.daniel.redirect.RedirectAction">
<result type="redirect">/users/Redirect.jsp</result>
</action>
jsp页面访问代码如下:
<s:property value="%{[0].name}"/>
结果是什么都没有,表明这个对象不存在,Action没有被压栈。6.redirectAction
重定向到动作,需要注意的是,配置了type="redirectAction"的那个动作,也是不会被压入到OGNL context的Object Stack中。一般地,这个结果要配置两个参数,一个是actionName,表示重定向的目的动作名称;另外一个是namespace,表示目的动作所在的命名空间 。因为我们访问动作都是:根目录/namespace/action这样子访问的,所以这两个参数我们很容易就可以记下来。namespace不是必须的,你如果没有配置,那么就使用当前包的namespace值。
以下代码说明配置了type="redirectAction"的那个动作,是不会被压入到OGNL context的Object Stack中。
RedirectToAction源码:
@SuppressWarnings("serial")
public class RedirectToAction extends ActionSupport {
private String property1 = "action1";
public String getProperty1() {
return property1;
}
public void setProperty1(String property1) {
this.property1 = property1;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return super.execute();
}
}
AcceptAction源码:
@SuppressWarnings("serial")
public class AcceptAction extends ActionSupport {
private String property2 = "action2";
public String getProperty2() {
return property2;
}
public void setProperty2(String property2) {
this.property2 = property2;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return super.execute();
}
}
struts.xml配置:
<package name="redirect" namespace="/" extends="struts-default">
<action name="action1" class="com.daniel.redirect.RedirectToAction">
<result type="redirectAction">
<param name="actionName">action2</param>
<param name="namespace">/</param>
</result>
</action>
<action name="action2" class="com.daniel.redirect.AcceptAction">
<result>/users/Redirect.jsp</result>
</action>
</package>
jsp访问代码:
<s:property value="%{[0].property2}"/>
<s:property value="%{[1].property1}"/>
7.type="stream"
这个结果是让服务器向浏览器传输二进制数据流的,最常用的情况是文件下载。一般地这个结果 会配置以下五个参数:contentLength、contentType、contentDisposition、inputName、bufferSize。这五个参数在我Struts文件下载的文章中进行讲解过,这里就不再重述。
8.type="velocity"
使用模板velocity作为结果,因为本人从来没有使用顾这种类型,也没有接触过velocity,所以这里跳过。
9.type="xslt"
这部分将在日后补充。
10.stype=:"plainText"
将内容作为纯文本输出,一般是将一些源代码显示出来。可以配置的参数有两个:location,表示资源所在的url;charSet,表示的页面的编码方式,因为默认的ISO-8859-1编码方式,是显示不了中文的。以下是一个配置例子:
<action name="PlainTextAction" class="com.daniel.action.plaintext.PlainTextAction">
<result name="success" type="plainText">
<param name="location">/users/ShowPlainTextPage.jsp</param>
<param name="charSet">UTF-8</param>
</result>
</action>
总结
不同的结果类型,需要配置不同的参数,在Struts开发文档中查询相关的结果类,就可以看到这个结果类能够配置的参数。