2011-05-10 67 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