struts2的validate错误跳转与chain配合使用的要点

探讨Struts2框架中Chain拦截器与特定Action方法之间的交互。当使用validate拦截器时,若验证失败并尝试转向目标Action的特定方法,如非input方法,则该方法不会被执行。本文深入分析了这一现象的原因,并提供了两种解决方案。
摘要由CSDN通过智能技术生成
本文基于struts2.1.8.1
按照struts2的官方文档,chain类型默认的目标Action跳转方法是execute(),摘录xwork的doc: method - used to specify another method on target action to be invoked. * If null, this defaults to execute method * * 在一般情况下,这没有问题。在使用validate拦截器拦截到错误,希望转到目标Action的特定方法时,却发现根本不执行。
为了描述方便清晰,先定义以上使用场景: FooAction有触发validate拦截器的相关验证代码,验证不通过触发workflow的跳转功能,默认转入FooAction的input结果指定的去向,即BarAction的某个方法,定义为someMethod()。网上有一则相关文章提到:如果在定向到input视图前有错误(如action的hasError方法返回true)和异常发生,且返回的input视图的type为"chain"(即返回到另一个action)时,这个action的方法必须为input,否则这个方法不会执行,而是会直接定位到物理视图。按照这个做法,的确可以进入指定input方法并且执行,可是并没有官方文档有类似说明,这是为什么呢?经过对validate、workflow拦截器的调试分析,终于揭秘了真相。
FooAction的validate拦截器执行相关的验证方法并得到了errors,通过workflow再chain到BarAction时,会过一遍BarAction的拦截器栈,也就是说,workflow拦截器会再次被执行,只不过此次是针对BarAction。看workflow的代码:

@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();

if (action instanceof ValidationAware) {
ValidationAware validationAwareAction = (ValidationAware) action;

if (validationAwareAction.hasErrors()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Errors on action " + validationAwareAction + ", returning result name 'input'");
}

String resultName = inputResultName;

if (action instanceof ValidationWorkflowAware) {
resultName = ((ValidationWorkflowAware) action).getInputResultName();
}

InputConfig annotation = action.getClass().getMethod(invocation.getProxy().getMethod(), new Class[0]).getAnnotation(InputConfig.class);
if (annotation != null) {
if (!annotation.methodName().equals("")) {
Method method = action.getClass().getMethod(annotation.methodName());
resultName = (String) method.invoke(action);
} else {
resultName = annotation.resultName();
}
}


return resultName;
}
}

return invocation.invoke();
}

在本场景中,由于FooAction验证的结果会通过chain传过来,validationAwareAction.hasErrors()的结果就是true,最终会走return resultName;也就是直接走了return "input",而不会进入action的someMethod方法。那为什么方法更名为input就可以了呢?原来,我们的配置文件里,对validate及workflow配置了

<param name="excludeMethods">input,back,cancel,browse</param>

input恰好就名列其中。也就是说,转向BarAction的input时,workflow是不进行拦截的,所以能进入BarAction的input方法。实际上,按照struts2的设计思想,input等方法就是用于错误处理的,不直接对前端提供服务,所以应该排除在validate和workflow之外。
这样,解决问题的方法就是:
1,利用struts2现有的机制,更改someMethod方法名为excludeMethods中现有的,最好是input,同时,chain的配置里,明确指定method参数为input,而不是默认的executed
2,把someMethod加入到validate和workflow的excludeMethods配置中
推荐第一种方法,不破坏struts2的设计思想。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值