Skip to content

Provide localized field name in JSR-303 validation messages [SPR-6407] #11073

Closed
@spring-projects-issues

Description

@spring-projects-issues

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

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions