学习目标:
1、了解Struts的结果集的使用
2、自定义resulttype
学习过程:
Result功能是封装Action层到View层的跳转逻辑。Struts2的Action是一个与Web容器无关的POJO。所以,在Action执行完毕之后,框架需要把代码的执行权重新交还给Web容器,并转向View层,有View层处理显示。这个跳转逻辑,就由Result来完成。
Struts2本身就已经对View层的显示类型的支持非常多,最常见的JSP和Freemarker/Velocity模板都可以支持。还可以Redirect到一个新的地址、图片流、JSON对对象,普通文本等等都可以。所以Result层的独立存在,就能够对这些显示类型进行区分,并封装合理的跳转逻辑。
一、result的type属性类型说明
result的type属性struts2已经帮我们定义下面这些:
dispatcher:默认结果类型,用来呈现JSP页面,请求转发,底层调用RequestDispatcher的forward()
chain:将action和另外一个action链接起来
freemarker:FreemarkerResult 呈现Freemarker模板
httpheader:返回一个已配置好的HTTP头信息响应
redirect:将用户重定向到一个已配置好的URL
redirectAction:将用户重定向到一个已定义好的action
stream:将原始数据作为流传递回浏览器端,一般用于文件的下载
velocity:呈现Velocity模板
xslt:呈现XML到浏览器,该XML可以通过XSL模板进行转换
plaintext:返回普通文本类容。
一般我们使得最多的就是下面四个:
Dispatcher 默认转发jsp
Chain action之间转发
Redirect 重定向
RedirectAction 重定向另外一个Action
具体应用,代码如下:
<action name="login" class="com.action.UserAction" method="login">
<!-- 默认是转发 -->
<result name="hi">/success.jsp</result>
<!-- 转发到另外一个action -->
<result name="ha" type="chain">
<param name="actionName">addgoods</param>
<param name="namespace">/goods</param>
</result>
<!-- 重定向 -->
<result name="error" type="redirect">/success.jsp</result>
<!-- 重定向Action -->
<result name="success" type="redirectAction">
<param name="actionName">addgoods</param>
<param name="namespace">/goods</param>
</result>
</action>
二、result的param标签的使用
在上面我们在result中使用param标签,这个标签还有很多功能。示例代码如下:
<!-- 这个重定向最后会生成url格式如下:域名/goods/addgoods.action?reportType=pie&width=300&height=200#summary -->
<action name="logout" class="com.action.UserAction" method="logout"><result name="success" type="redirectAction">
<param name="actionName">addgoods</param>
<param name="namespace">/goods</param>
<param name="reportType">pie</param>
<param name="width">300</param>
<param name="height">200</param>
<param name="anchor">summary</param>
</result>
</action>
三、定义全局的result
我们还可以在包标签中定义一个全局的result,这样对如果每一个action都用相同的result定义时,就可以使用全局result。例如,我们的的所有的action都有这样的已经定义
<result name="error" type="redirect">/error.jsp</result>
那么我们可以在包package标签下中定义一个全局的result,那么在这个包package和它的子包都可以使用这个全局的定义。
<result name="error" type="redirect">/error.jsp</result>
我们还可以结合使用全局异常导向global-exception-mappings标签,屏蔽系统的所有的异常。因为一旦发生异常,所有的异常信息都会展示在页面上。使用全局异常导向global-exception-mappings可以提高系统的安全性和用户体验。代码如下:
<global-results>
<result name="error" type="redirect">/error.jsp</result>
</global-results>
<global-exception-mappings>
<!-- 发生异常是返回name为error的result -->
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
struts2设计非常好,除了它本身功能非常强大之外,我们还可以非常容易扩展它的功能,这里我们尝试一下自定义新的result类型。
四、自定义result的type类型
要扩展result,只需要实现Result接口即可,示例代码如下:
/**
* 自定义的result类型的实现类
*
* @author Administrator
*
*/
public class MyResult implements Result {
/**
*
*/
private static final long serialVersionUID = 1L;
public void execute(ActionInvocation ai) throws Exception {
HttpServletRequest request = (HttpServletRequest)ai.getInvocationContext().get(
StrutsStatics.HTTP_REQUEST);
HttpServletResponse response=(HttpServletResponse)ai.getInvocationContext().get(
StrutsStatics.HTTP_RESPONSE);
response.setCharacterEncoding("UTF-8");
PrintWriter writer=response.getWriter();
//获得users,通过值栈获得
ValueStack valueStack=ai.getStack();
List<User> users=(List<User>)valueStack.findValue("users");
//标识以文本方式输出
response.setContentType("text/plain");
for(User user:users){
writer.write(user.getUsername()+":"+user.getPasswd()+"|");
}
writer.flush();
writer.close();
}
}
在struts.xml配置文件中配置这个新的result类型,必须package标签里面配置,这样,在这个包里面,以及所有继承这个package的其它package都可以使用这个result类型了。代码如下:
<struts>
<!-- 是否是开发模式 true 部署前真正运行前一定要改为false -->
<constant name="struts.devMode" value="false" />
<package name="default" namespace="/" extends="struts-default">
<result-types>
<result-type name="myresult" class="com.myresulttypes.MyResult"></result-type>
</result-types>
</package>
</struts>
在UserAction中实现一下代码
private List<User> users;
/**
* 使用自定义的result 类型
* @return
*/
public String userlist(){
UserDao userDao=new UserDao();
users=userDao.getAll();
return SUCCESS;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
修改struts.xml的配置文件,使用这个result类型。
<struts>
<!-- 是否是开发模式 true 部署前真正运行前一定要改为false -->
<constant name="struts.devMode" value="false" />
<package name="default" namespace="/" extends="struts-default">
<result-types>
<result-type name="myresult" class="com.myresulttypes.MyResult"></result-type>
</result-types>
<action name="userlist" class="com.action.UserAction" method="userlist">
<result name="success" type="myresult"></result>
</action>
</package>
</struts>
在index.jsp文件中新建一个超链接访问,并查看测试结果。
<a href="userlist.action">用户列表</a>