我通过设置从调用者操作到被调用操作的错误引用来解决这个问题。这是作为拦截器实现的:
public class CopyErrorsInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
ValueStack stack = invocation.getStack();
CompoundRoot root = stack.getRoot();
Action currentAction = (Action) invocation.getAction();
if (root.size() > 1 && isValidationAware(currentAction)) {
Action callerAction = getFirstActionBelow(root, currentAction);
if (callerAction != null && isValidationAware(callerAction)) {
ValidationAware currentActionVal = (ValidationAware) currentAction;
ValidationAware callerActionVal = (ValidationAware) callerAction;
//Copy the errors to the chained action.
currentActionVal.setActionErrors(callerActionVal.getActionErrors());
currentActionVal.setFieldErrors(callerActionVal.getFieldErrors());
}
}
return invocation.invoke();
}
/**
* Gets the first action below the passed action.
* @param root the stack to find the action
* @param current is the current action.
* @return
*/
private Action getFirstActionBelow(CompoundRoot root, Action current) {
boolean foundCurrentAction = false;
for(Object obj : root) {
if (obj == current) {
foundCurrentAction = true;
} else {
if (obj instanceof Action && foundCurrentAction) {
return (Action) obj;
}
}
}
return null;
}
private boolean isValidationAware(Action action) {
return action instanceof ValidationAware;
}
}
必须声明自己的堆栈,该堆栈扩展Struts默认值:
<interceptors>
<interceptor name="copyErrors" class="com.afirme.casa.interceptor.CopyErrorsInterceptor"/>
<interceptor-stack name="defaultPlusErrors">
<interceptor-ref name="copyErrors"/>
<interceptor-ref name="defaultStack">
<param name="workflow.excludeMethods">
input,back,cancel,execute
</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
对于将被其他操作(在本例中是通过操作标签)阻止的操作,必须引用这个新的拦截器堆栈。例子:
<action name="example" class="ExampleAction">
<interceptor-ref name="defaultPlusErrors"/>
<result>/jsp/example.jsp</result>
</action>
希望这有帮助,
阿尔弗雷多o