Spring Boot 2.1.5: Failed to replace {0} with Field Name on Validation Message

Viewed 716

I am trying to upgrade spring-boot 2.1.4 to 2.1.5.

In spring-boot 2.1.4, custom validation error message with {0} arguments correctly replace with Field Name. But spring-boot 2.1.5, validation error message shows {0} as it is.

code

  • messages.properties
notblank={0} must not be blank
  • PersonForm
import javax.validation.constraints.NotBlank;

class PersonForm {

    @NotBlank(message = "{notblank}")
    private String name;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return "Person(Name: " + this.name + ")";
    }
}

Here's my sample project.
https://github.com/spikefin-goby/spring-boot-validation-sample

spring-boot 2.1.4 result

In spring-boot 2.1.4, display 「name must not be blank」
(correctly replace {0} with Field Name )
spring-boot 2.1.4 validation message

BingingResult.errors[0] is FieldError class


spring-boot 2.1.5 result

But spring-boot 2.1.5, display 「{0} must not be blank」
spring-boot 2.1.5 validation message

BingingResult.errors[0] is LocalValidatorFactoryBean class


What can I do about this?


Update

Spring Boot 2.1.6 has been released in June 19, 2019. This problem is fixed!

In spring-boot 2.1.6, display 「name must not be blank」
(correctly replace {0} with Field Name )

2 Answers

You could do this with an Exception Handler like this:

public ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex) {
    List<String> errors = new ArrayList<>();
    for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
        String error = String.format("%s.%s: %s", violation.getRootBeanClass().getSimpleName(),
                violation.getPropertyPath(), violation.getMessage());
        errors.add(error);
        logger.error(error);
    }

    ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, errors);
    return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus());
}

violation.getPropertyPath() returns the name of the field that threw the violation.

As a side note: I'm using my self made class ApiError to display errors. You don't need to do it that way but it's important that you iterate the constraint violations inside your ConstraintViolationException to get the property path of each of them.

Related