转自:http://blog.youkuaiyun.com/xingfuzhijianxia/article/details/6977992
action的默认结果类型是dispatcher,而action之间发送请求是不能直接用该结果类型的。一般来说,可选的结果有redirect、redirect-action、chain。前两种都是属于页面跳转,也就是说,发送请求以后,地址栏的地址会刷新为被请求的action的地址,而chain则不会更新地址。
redirect-action:“这个Result使用ActionMapperFactory提供的ActionMapper来重定位浏览器的URL来调用指定的action和(可选的)namespace. 这个Result比ServletRedirectResult要好.因为你不需要把URL编码成xwork.xml中配置的ActionMapper提供的模式. 这就是说你可以在任意点上改变URL模式而不会影响你的应用程序. 因此强烈推荐使用这个Result而不是标准的redirect result来解决重定位到某个action的情况.”---webwork2的说法。
redirect:“调用{@link HttpServletResponse#sendRedirect(String) sendRedirect}方法来转到指定的位置。HTTP响应被告知使浏览器直接跳转到指定的位置(产生客户端的一个新请求). 这样做的结果会使刚刚执行的action(包括action实例,action中的错误消息等)丢失, 不再可用。”
简单说,两者的共同点是,地址栏会变化,所有前一个action的请求参数都会丢失,当然也包括action的属性值也会丢失。路径写法稍有不同,redirect-action请求下一个action时,不带后缀.action,而redirect和普通URL写法一致。redirect-action支持param来附加请求参数,但是这往往会导致ServletActionRedirectRes
chain:相当于是forward,首先表现为地址栏不会改变,类似dispatcher,同时,它的特点是能够在多个action中共享表单传递过来的数据,同时,按照action链的顺序,相关action的属性值也会传递下去,这表示在最后的视图页,你可以得到前面所有action的属性值(如果有get方法的话)。对于多个action具有相同属性值的话,后续action会先使用前面的action的数据来进行赋值,然后再进行逻辑处理并传递下去。
看起来是很完美,可是却有很大的问题。如果后面的action需要调用前面action的属性值,他得保证具有同样的属性值,否则你无法接收到前面action的值。他无法像redirect-action一样通过附加参数获取,他不支持xxx?a=x&b=y的形式。这将导致很大的耦合性和无效参数的泛滥,无法通过配置文件传递参数也很麻烦。
另外,很困扰的一点就是,如果在action链靠前的action方法内出现错误(如action的hasError方法返回true)或者发生异常,他就会强迫你定义input结果,包括后面的action也要定义,否则就会报错。而实际上,即使符合了以上条件,他仍不会执行后面的action,而是直接跳到后面的action的input视图。除非发生错误的action返回input,并且type为“chain”,并且后一个action的方法必须为input,否则后续方法不会执行,而直接定位到了最后的物理视图。
这让我觉得chain的适用范围变的十分窄,据说webwork2已经不提倡使用chain,这个没考证过。
转自:http://www.iteye.com/topic/595519
自己在实践的时候发现了一些问题,比如:需要将表单中的数据封装在User中,提交给firstAction处理,再将处理后的user传递给secondAction作处理。
表单如下:
- <s:form action="firstAction">
- <s:textfield name="user.name" label="name" />
- <s:password name="user.password" label="password" />
- <s:submit />
- </s:form>
UserAction.java代码如下:
- package st.action;
- import com.opensymphony.xwork2.Action;
- import st.bean.User;
- public class UserAction {
- private User user;
- public User getUser() {
- return user;
- }
- public void setUser(User user) {
- this.user = user;
- }
- public String firstAction() {
- user.setName(user.getName() + "_FIRST");
- user.setPassword(user.getPassword() + "_FIRST");
- System.out.println(user.getName() + "," + user.getPassword());
- System.out.println(this + "," + user);
- return Action.SUCCESS;
- }
- public String secondAction() {
- user.setName(user.getName() + "_SECOND");
- user.setPassword(user.getPassword() + "_SECOND");
- System.out.println(user.getName() + "," + user.getPassword());
- System.out.println(this + "," + user);
- return Action.SUCCESS;
- }
- }
起先我是使用redirectAction,配置如下:
- <action name="firstAction" class="st.action.UserAction" method="firstAction">
- <result name="success" type="redirectAction">
- <param name="actionName">secondAction</param>
- <param name="user.name">${user.name}</param>
- <param name="user.password">${user.password}</param>
- </result>
- </action>
- <action name="secondAction" class="st.action.UserAction" method="secondAction">
- <result>result.jsp</result>
- </action>
通过打印出来的结果,可以发现虽然user的值被传递给了secondAction,但其实是重新实例化了一个user。如果要做到传递对象貌似没有什么办法,而且参数内容也被显示在了地址栏上。
使用redirect也是同样的问题。
如果使用chain又是另外一回事儿了:
- <action name="firstAction" class="st.action.UserAction" method="firstAction">
- <result name="success" type="chain">secondAction</result>
- </action>
- <action name="secondAction" class="st.action.UserAction" method="secondAction">
- <result>result.jsp</result>
- </action>
结果,前一次user处理后的值并没有传给secondAction,secondAction只是处理表单上的数据。
如果想要完成user对象在action中的传递,难道一定要借助session么?
ps:1 redirect:action处理完后重定向到一个视图资源(如:jsp页面),请求参数全部丢失,action处理结果也全部丢失。
2 redirect-action:action处理完后重定向到一个action,请求参数全部丢失,action处理结果也全部丢失。
3 chain:action处理完后转发到一个action,请求参数全部丢失,action处理结果不会丢失。