I have the following situation. I have a validator to validate my command object and set the errors on a Errors object to be displayed in my form. The validator is invoked as expected and works okay, but the errors i set on the Errors objects are not displayed, when i am sent back to my form because of the validation errors.
Validator:
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");
}
}
Command:
public class MyCommand {
private List<Field> fields;
private int limit;
//g开发者_StackOverflow社区etters and setters
}
public class Field {
private boolean checked;
private String name;
private String value;
//getters and setters
}
Form:
<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>
Controller:
@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
}
Could it be that the paths i give in the validator and tag are not correct? The validator validates a command object containing a list of objects, so that's why i give a index on the list in the command object when registering an error message (for example: "fields["+index+"]".value). Or is it that the Errors object containing the errors is not available to my view?
Any help is welcome and appreciated, it might give me a hint or point me in right direction.
I found what is your problem.
property fields
in object myCommand
always null.
You need to create constructor for class MyCommand in which you need to use LazyList
from Apache Commons or AutoPopulatingList
from Spring to create auto growing list of Field
In example (using AutoPopulatingList):
public class MyCommand {
private List<Field> fields;
private int limit;
//getters and setters
//...
//Constructor
public MyCommand() {
fields = new AutoPopulatingList<Field>(Field.class);
}
}
The line err.rejectValue("fields[" + index + "].value", "errors.missing");
will not do what you are trying to achieve. The first argument must be a property name of your Command bean, in your case fields.
To give the user a message you will have to use a parameterizable message in your properties file, eg. myform.field.error = you have an error in field {0}
So, use this method of the Errors object:
void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage)
Where you pass index
into errorArgs
精彩评论