2010-03-17 115 views
11

我有以下情況。我有一個驗證器來驗證我的命令對象,並將錯誤對象上的錯誤設置爲顯示在我的表單中。驗證程序按預期方式調用並且工作正常,但是由於驗證錯誤,我在錯誤對象中設置的錯誤不會顯示,因爲我發回到表單。未顯示彈簧驗證錯誤

驗證:

public void validate(Object obj, Errors err) { 
    MyCommand myCommand = (MyCommand) obj; 
    int index = 0; 
    for (Field field : myCommand.getFields()) { 
     if (field.isChecked()) { 
      if ((field.getValue() == null) || (field.getValue().equals(""))) { 
       err.rejectValue("fields[" + index + "].value", "errors.missing"); 
      } 
     } 
     index++; 
    } 
    if (myCommand.getLimit() < 0) { 
     err.rejectValue("limit", "errors.invalid"); 
    } 
} 

命令:

public class MyCommand { 
    private List<Field> fields; 
    private int limit; 

    //getters and setters 
} 

public class Field { 
    private boolean checked; 
    private String name; 
    private String value; 

    //getters and setters 
} 

形式:

<form:form id="myForm" method="POST" action="${url}" commandName="myCommand"> 
    <c:forEach items="${myCommand.fields}" var="field" varStatus="status"> 
     <form:checkbox path="fields[${status.index}].checked" value="${field.checked}" /> 
     <c:out value="${field.name}" /> 
     <form:input path="fields[${status.index}].value" /> 
     <form:errors path="fields[${status.index}].value" cssClass="error" /></td> 
     <form:hidden path="fields[${status.index}].name" /> 
    </c:forEach> 
    <fmt:message key="label.limit" />  
    <form:input path="limit" /> 
    <form:errors path="limit" cssClass="error" /> 
</form:form> 

控制器:

@RequestMapping(value = REQ_MAPPING, method = RequestMethod.POST) 
    public String onSubmit(Model model, MyCommand myCommand, BindingResult result) { 
    // validate 
    myCommandValidator.validate(myCommand, result); 
    if (result.hasErrors()) { 
     model.addAttribute("myCommand", myCommand); 
     return VIEW; 
    } 

    // form is okay, do stuff and redirect 
} 

難道我在驗證器和標籤中給出的路徑不正確?驗證器驗證包含對象列表的命令對象,所以這就是爲什麼當註冊錯誤消息(例如:「fields [」+ index +「]」.value)時,我在命令對象的列表中給出索引。 或者它是否包含錯誤的錯誤對象不可用於我的視圖?

任何幫助,歡迎和讚賞,它可能會給我一個暗示或指向我在正確的方向。

+0

嘗試添加 在您的表單代碼中確保您的驗證器正常工作 – 2010-03-19 15:44:34

回答

1

err.rejectValue("fields[" + index + "].value", "errors.missing");不會做你想要實現的。第一個參數必須是你的Command bean的屬性名稱,在你的case域中。

要給用戶一條消息,你將不得不在你的屬性文件中使用可參數化的消息,例如。 myform.field.error = you have an error in field {0}

因此,使用錯誤的這種方法對象:

void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage) 

當你通過index到errorArgs

+0

感謝您的回覆mirror303。我沒有準確得到的是你將索引傳入errorArgs的意思。我假設errorArgs是我的屬性文件中參數化消息的參數,並且與索引命令屬性(如List)無關。但可能我不明白你在說什麼。那麼,你的意思是說,Args的值應該是「fields [」+ index +「]。value」? – 2010-03-19 10:27:47

+0

是索引,如你在你發佈的代碼中使用的方法變量 – 2010-03-19 11:06:48

+0

但是索引是一個int而不是一個Object []和fields [index] .value是一個String,所以我沒有看到如何使用索引i可以提供一個Object []作爲參數。 – 2010-03-19 11:41:39

3

我發現你有什麼問題。 屬性fields對象myCommand始終爲空。 您需要創建類mycommand的構造函數中,你需要使用Apache的共享LazyListAutoPopulatingList從Spring構建Field

在示例(使用AutoPopulatingList)汽車越來越多:

public class MyCommand { 
    private List<Field> fields; 
    private int limit; 

    //getters and setters 
    //... 
    //Constructor 
    public MyCommand() { 
     fields = new AutoPopulatingList<Field>(Field.class); 
    } 
} 
+1

我終於得到了我的表單驗證工作。事實證明,Spring將BindingResult對象添加到模型中,但是以不同的名稱(類名以小寫開頭)比我在表單標記中使用的命令名稱更加簡單。更改命令名以反映Spring用來將BindingResult添加到模型的名稱,使我的表單驗證按預期工作。無論如何,感謝你的努力和幫助。 PS。爲什麼需要LazyList?因爲沒有它,我的表單似乎工作正常。 – 2010-03-22 11:26:08

+0

我同意Yuri.Bulkin的回答。 我在2個月前面臨同樣的問題,我找到了這個解決方案。在* jsp *使用* spring *的* form *標記中使用字段列表之前,您需要進行'LazyList'初始化。 – 2012-05-05 05:37:23