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