shigemoto
shigemoto

Reputation: 78

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

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

notblank={0} must not be blank
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 )

Upvotes: 4

Views: 889

Answers (2)

Lesiak
Lesiak

Reputation: 25966

To my eyes, you run into the issue #23014: validation error message {0} is not working in spring-context-5.1.7

Upvotes: 1

Mirko Brandt
Mirko Brandt

Reputation: 475

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.

Upvotes: 0

Related Questions