ConversionErrorInterceptor在退出/取消期间抛出转换错误(Struts 2)

时间:2011-05-10 07:49:36

标签: struts2 interceptor

问题的情况是这个

1)我们将struts字段值映射到dtos。 dtos包含再次显示在屏幕上的整数字段。

2)现在我输入一个不正确的值,它给出了整数字段的转换错误。

3)在那个时候我决定退出页面(即按取消),我收到转换错误。这是因为每次都会调用StrutsConversionErrorInterceptor。

当我调用特定方法时,有没有办法可以跳过strutsConversionErrorInterceptor,就像我们可以使用excludeMethods跳过验证一样

3 个答案:

答案 0 :(得分:0)

是的,你可以跳过调用拦截器。

只需从struts.xml文件中的操作定义中删除拦截器定义即可。 即,删除<interceptor-ref name="conversionError"/>

主要是这个拦截器将ActionContext的conversionErrors映射中发现的任何错误添加为字段错误(假设该操作实现了ValidationAware)。此外,包含验证错误的任何字段都会保存其原始值,以便对该值的任何后续请求都返回原始值而不是操作中的值。这很重要,因为如果提交值“abc”并且无法转换为int,我们想再次显示原始字符串(“abc”)而不是int值(可能为0,这很有意义)给用户)。

删除此拦截器后,如果struts无法使用对象的参数(即从string到int)映射字段,则会抛出结果输入操作错误。

答案 1 :(得分:0)

使用此代码覆盖Struts的StrutsConversionErrorInterceptor ...

public class MyConversionErrorInterceptor extends AbstractInterceptor {

    private static final long serialVersionUID = 1L;

    public static final String ORIGINAL_PROPERTY_OVERRIDE = "original.property.override";

    protected Object getOverrideExpr(ActionInvocation invocation, Object value) {
         ValueStack stack = invocation.getStack();

            try {
                stack.push(value);

                return "'" + stack.findValue("top", String.class) + "'";
            } finally {
                stack.pop();
            }
    }

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {

        ActionContext invocationContext = invocation.getInvocationContext();
        Map<String, Object> conversionErrors = invocationContext.getConversionErrors();
        ValueStack stack = invocationContext.getValueStack();

        HashMap<Object, Object> fakie = null;

        BaseAction baseAction = (BaseAction) invocation.getAction();
        String buttonName = baseAction.getButtonName();

        for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) {
            String propertyName = entry.getKey();
            Object value = entry.getValue();

            if (shouldAddError(propertyName, value)) {
                String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);

                Object action = invocation.getAction();
                if (action instanceof ValidationAware) {
                    ValidationAware va = (ValidationAware) action;
                      if(buttonName.equalsIgnoreCas("Next")){
                          va.addFieldError(propertyName, message);
                      }
                }

                if (fakie == null) {
                    fakie = new HashMap<Object, Object>();
                }
                 if(buttonName.equalsIgnoreCas("Next")){
                     fakie.put(propertyName, getOverrideExpr(invocation, value));
                 }
            }
        }

        if (fakie != null) {
            // if there were some errors, put the original (fake) values in
            // place right before the result
            stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie);
            invocation.addPreResultListener(new PreResultListener() {
                public void beforeResult(ActionInvocation invocation, String resultCode) {
                    Map<Object, Object> fakie = (Map<Object, Object>) invocation.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE);

                    if (fakie != null) {
                        invocation.getStack().setExprOverrides(fakie);
                    }
                }
            });
        }

        return invocation.invoke();
    }

    protected boolean shouldAddError(String propertyName, Object value) {

        if (value == null) {
            return false;
        }

        if ("".equals(value)) {
            return false;
        }

        if (value instanceof String[]) {
            String[] array = (String[]) value;

            if (array.length == 0) {
                return false;
            }

            if (array.length > 1) {
                return true;
            }

            String str = array[0];

            if ("".equals(str)) {
                return false;
            }
        }

        return true;

    }

}

您可以指定要激活验证的按钮名称。在上面的代码中,我在代码中使用了“Next”

如果(buttonName.equalsIgnoreCas( “下一个”))

答案 2 :(得分:0)

这似乎是处理此方案的更好方法 - 使用Conversion ValidatorRepopulating Field upon conversion Error部分非常有用:

http://struts.apache.org/2.0.14/docs/conversion-validator.html