Description
Sebastian Beigel opened SPR-6407 and commented
I think it would be a good idea to provide the (localized) field name in JSR-303 validation messages as the first argument ("{0}"). It would be consistent with Spring's other validation (type conversion) messages and essential if you want to show a validation error summary (vs. showing the error message next to the input field in the UI, i.e. "Foo must match [a-z]+").
I have extended LocalValidatorFactoryBean and overridden validate(Object target, Errors errors) to include the field name (as a DefaultMessageSourceResolvable) as the first argument. But I think it should be included directly in LocalValidatorFactoryBean (i.e. SpringValidatorAdapter).
The code could look something like this (sorry, too lazy to make a patch :)
public void validate(Object target, Errors errors) {
Set<ConstraintViolation<Object>> result = getValidator().validate(target);
for (ConstraintViolation<Object> violation : result) {
String field = violation.getPropertyPath().toString();
FieldError fieldError = errors.getFieldError(field);
if (fieldError == null || !fieldError.isBindingFailure()) {
// build argument list...
Collection<Object> args = new ArrayList<Object>();
// ...containing the localized field name as first arg (trying the codes "model.field" and "field")...
args.add(new DefaultMessageSourceResolvable(new String[] { errors.getObjectName() + "." + field, field }));
// ...and JSR-303 validator's other arguments
args.addAll(violation.getConstraintDescriptor().getAttributes().values());
errors.rejectValue(field,
violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(),
args.toArray(),
violation.getMessage());
}
}
Resolving to messages like this:
Pattern={0} must match {4}!
model.field=Foo
field=Bar
=> Foo must match [a-z]+
Of course you could provide all the messages in the "direct" form: "Pattern.field=Field must match {4}" (w/out the patch) -- but this is cumbersome and redundant :)
Affects: 3.0 RC2
Referenced from: commits 69124f9