2011-05-10 46 views
0

问题的方案是这样的ConversionErrorInterceptor期间抛出转换错误退出/取消(在Struts 2)

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

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

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

有没有办法,我可以跳过strutsConversionErrorInterceptor当我打电话的特定方法,我们可以使用excludeMethods

回答

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; 

    } 

} 

您可以指定要验证你被解雇了按钮名称。在上面的代码中,我已经使用“下一步”在代码中你可以看到

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

0

是的,你可以跳过调用拦截跳过验证过程中的任何方式。

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

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

删除此拦截器后,如果struts无法将对象的参数(即从字符串到int)映射到字段,则会引发结果输入操作错误。

+0

好像有没有更简单的方法 – Vijay 2011-05-19 09:56:31

相关问题