一、引言
本文介绍Struts2配置文件中result的type属性值:redirect,redirectAction,chain的区别。
首先简要介绍这三者的意思。
1)redirect: action处理完后重定向到一个视图资源(如:jsp页面),请求参数全部丢失,action处理结果也全部丢失。
2)redirectAction: action处理完后重定向到一个action,请求参数全部丢失,action处理结果也全部丢失。
3)chain: action处理完后转发到一个action,请求参数全部丢失,action处理结果不会丢失。
二、测试
下面我们开始建立测试用例。
这里我们以用户注册为例,分别两个Action来模拟以上三个请求转发的类型的测试。
1.创建User类,由于本例目的在测试三种请求转发方式,所以User类设计得比较简单。
package org.xjh.domain;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password="
+ password + "]";
}
}
2.创建Action1,Action1会先收到用户在注册页面提交过来的注册请求(当然这里只是用作模拟并未操作数据库)
package org.xjh.struts.action;
import org.apache.struts2.ServletActionContext;
import org.xjh.domain.User;
public class Action1 {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() {
//为了区分,我们在后面多加了_first这个标记,以表明这是由Action1接收到的数据
user.setUsername(user.getUsername() + "_first");
user.setPassword(user.getPassword() + "_first");
System.out.println(user);
System.out.println("First User Hashcode = " + user.hashCode());
//存入提示信息,用于判断redirect,redirectAction,chain转发请求是否丢失数据
ServletActionContext.getRequest().setAttribute("message", "注册成功!");
return "success";
}
}
3.创建Action2类
package org.xjh.struts.action;
import org.apache.struts2.ServletActionContext;
import org.xjh.domain.User;
public class Action2 {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() {
//为了区分,我们在后面多加了_second这个标记,以表明这是由Action2接收到的数据
user.setUsername(user.getUsername() + "_second");
user.setPassword(user.getPassword() + "_second");
System.out.println(user);
System.out.println("Second User Hashcode = "+ user.hashCode());
//存入提示信息,用于判断redirect,redirectAction,chain转发请求是否丢失数据
ServletActionContext.getRequest().setAttribute("message", "注册成功!");
return "success";
}
}
4.创建注册页面register.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
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>
<title>测试</title>
</head>
<body>
<h3>欢迎注册</h3>
<form action="<%=path %>/firstAction" method="post">
用户名: <input type="text" name="user.username" > <p/>
密码: <input type="password" name="user.password" > <p/>
<input type="submit" value="注册" />
</form>
</body>
</html>
5.消息提示页
<%@ page import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>提示信息</title>
</head>
<body>
${message}
</body>
</html>
6.配置处理注册请求的action
这里我们首先测试result type="redirect",即redirect转发请求。
<package name="user" namespace="/" extends="struts-default">
<action name="firstAction" class="org.xjh.struts.action.Action1" >
<result name="success" type="redirect">/message.jsp</result>
</action>
<action name="secondAction" class="org.xjh.struts.action.Action2" >
<result name="success">/message.jsp</result>
</action>
</package>
7.测试
1)测试redirect转发请求
打开浏览器,在地址栏中输入访问register.jsp页面的url
用户名和密码分别输入:test, 123 。点击注册按钮。
你会发现地址栏的url发生了变化,这表明redirect是客户端重定向的方式跳转的。
同时在MyEclipse的控制台窗口,你会看到如下信息:
2)测试redirectAction转发请求
修改struts的配置文件,如下:
<package name="user" namespace="/" extends="struts-default">
<action name="firstAction" class="org.xjh.struts.action.Action1" >
<result name="success" type="redirectAction">
<param name="namespace">/</param>
<param name="actionName">secondAction</param>
<param name="user.username">${user.username}</param>
<param name="user.password">${user.password}</param>
</result>
</action>
<action name="secondAction" class="org.xjh.struts.action.Action2" >
<result name="success">/message.jsp</result>
</action>
</package>
回到注册页面,用户名和密码分别输入:test, 123 。点击注册按钮。
你会发现地址栏的url变成了aciton1请求action2的url,这表明redirectAction是客户端重定向的方式跳转的,并且浏览器页面中得到如下提示信息:
同时在MyEclipse的控制台窗口,你会看到如下信息:
这表明第二个Action(Action2)得到的User信息来自第一个Action(Action1)处理过的User信息,而且这两两个对象的地址是不同的(Hashcode不同)
3)测试chain
修改struts的配置文件,如下:
<package name="user" namespace="/" extends="struts-default">
<action name="firstAction" class="org.xjh.struts.action.Action1" >
<result name="success" type="chain">
<param name="namespace">/</param>
<param name="actionName">secondAction</param>
</result>
</action>
<action name="secondAction" class="org.xjh.struts.action.Action2" >
<result name="success">/message.jsp</result>
</action>
</package>
回到注册页面,用户名和密码分别输入:test, 123 。点击注册按钮。
你会发现地址栏的url只是变成了请求action1的url,这表明chain是以服务端重定向的方式跳转的,并且浏览器页面中得到如下提示信息:
由上面信息可以看出,Action1处理过的User对象信息并未直接传给Action2,在jsp页面提交的请求数据被重新装到一个User对象中,而这个User对象
被Action1中的User变量引用,同时也被Action2的User变量所引用,这点由它们的Hashcode相同可得出。
三、总结
redirect表示客户端重定向,用于重定向到某个页面。
redirectAction也表示客户端重定向,用于重定向到某个Action
chain表示服务端请求转发,用于多个Action之间数据信息的共享。
redirect和redirecAction类似于response.sendRedirect(url);
chain类似于request.getRequestDispatcher(url).forward(request, response);