2010-03-17 112 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