事实上我也不知道这属于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没有问题,只有addActionErrorredirect 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 inputResultName     * 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则没什么问题。