事实上我也不知道这属于bug还是功能。
在此简短描述一番,希望可以得到帮助。
有一个信息修改页,点击保存后会dispatch到信息列表页。
然后我点击信息明细,进入页面后有一个返回按钮。
为了方便起见,我直接写了location.href = document.referrer;
但此时referrer是保存信息的action URL。
于是我将保存信息的action的result type改为redirect action。
保存信息时我会调用一个远程方法。
调用失败后再调用一次,再次失败时会抛出异常。
然后我在action方法中catch这个异常,并调用addActionError,在页面中显示这个action error。
该方法在开发环境中一直都是访问不了,所以每次都是抛出异常。
但这次抛出了两个异常,第二个异常让我诧异。
提示我no result defined for action...DefaultActionInvocation你懂的...
/** * Uses getResult to get the final Result and executes it * * @throws ConfigurationException If not result can be found with the returned code */ private void executeResult() throws Exception { result = createResult(); String timerKey = "executeResult: " + getResultCode(); try { UtilTimerStack.push(timerKey); if (result != null) { result.execute(this); } else if (resultCode != null && !Action.NONE.equals(resultCode)) { throw new ConfigurationException("No result defined for action " + getAction().getClass().getName() + " and result " + getResultCode(), proxy.getConfig()); } else { if (LOG.isDebugEnabled()) { LOG.debug("No result returned for action " + getAction().getClass().getName() + " at " + proxy.getConfig().getLocation()); } } } finally { UtilTimerStack.pop(timerKey); } }
result返回null,resultCode莫名其妙编程INPUT。
起初以为是我抛出异常的问题,但我在action方法中却catch了。
后来发现原来是addActionError方法惹得祸,而addActionMessage却没有问题。
此时dispatch没有问题,只有addActionError后redirect action出现这种问题。
应该是哪个interceptor中做了处理,可能是validationInterceptor吧...
但我找不到具体代码在哪里,先在这里记录一下。
后来我在爆栈里找到了答案。
interceptor chain中默认带一个DefaultWorkflowInterceptor。
这个interceptor通常和validation interceptor一起工作,如果action实现了validatable也会调用其validata方法。如果发现了action error或者field error,则中断过滤器链并立即返回一个"input"result。
在我的例子中,我从未定义过name="input"的result,于是直接给我来了个no result defined for action...
/** * Intercept {@link ActionInvocation} and returns a <code>inputResultName</code> * when action / field errors is found registered. * * @return String result name */ @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 [#0], returning result name [#1]", validationAwareAction, inputResultName); } String resultName = inputResultName; resultName = processValidationWorkflowAware(action, resultName); resultName = processInputConfig(action, invocation.getProxy().getMethod(), resultName); resultName = processValidationErrorAware(action, resultName); return resultName; } } return invocation.invoke(); }
除非做特殊处理保存这个error,不然在redirect过程中会丢失。
当然,就算是redirect action也是同理。
但是,此时用dispatch则没什么问题。