Spring Framework 6.1.3 introduced a regression in MVC where validation error details are not returned anymore for REST endpoints in certain cases. These settings in Spring Boot become ineffective:
server.error.include-binding-errors=always
server.error.include-message=always
I created a minimal sample application to demonstrate the issue: https://github.com/notizklotz/spring-boot-322-validation-regression
The bug appears at least in these conditions:
- Spring Boot 3.2.2 and 3.2.3 (Spring Framework 6.1.3 and 6.1.4)
- One of the method parameters has a jakarta.validation.constraints
constraint.
- Validation on a another parameter fails, which is a @Valid
annotated Pojo.
With Spring Boot 3.2.0 and 3.2.1 (Spring Framework 6.1.1 and 6.1.2) the validation error of the Pojo results in a MethodArgumentNotValidException
:
2024-03-08T07:41:14.526+01:00 WARN 38155 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [1] in public void com.example.demo.DemoApplication.withConstraintOnPathVariable(java.lang.String,com.example.demo.DemoApplication$RequestData): [Field error in object 'requestData' on field 'propertyA': rejected value []; codes [NotBlank.requestData.propertyA,NotBlank.propertyA,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [requestData.propertyA,propertyA]; arguments []; default message [propertyA]]; default message [must not be blank]] ]
With Spring Boot 3.2.2 and 3.2.3 (Spring Framework 6.1.3 and 6.1.4) this results in a HandlerMethodValidationException
:
2024-03-08T07:40:18.447+01:00 WARN 37706 --- [nio-8080-exec-1] .w.s.m.a.ResponseStatusExceptionResolver : Resolved [org.springframework.web.method.annotation.HandlerMethodValidationException: 400 BAD_REQUEST "Validation failure"]
This issue seems to be related to the changes made for #32007
Comment From: quaff
@notizklotz Your sample application code repository is private.
Comment From: notizklotz
@quaff I made it public now. Sorry about that!
Comment From: rstoyanchev
Thanks for the sample.
Although it does look like it, it's not actually a regression. Given this method signature:
@PostMapping("/api/{mypath}/with-constraint")
public void withConstraintOnPathVariable(
@PathVariable @Pattern(regexp = "[a-z0-9-]+") String mypath,
@RequestBody @Valid RequestData mydata) {
}
Method validation applies, and the @RequestBody
resolver should recognize that, and refrain from validating individually, and defer to method validation instead, or otherwise it leads to validation being performed twice, and also to raising different exceptions, MethodArgumentNotValidException
vs MethodValidationException
, depending on whether one or both parameters have validation issues.
In 6.1.2 the resolver applies validation, not by intent, and raises MethodArgumentValidation
, precluding the use of method validation. The cause is explained in https://github.com/spring-projects/spring-framework/issues/31711#issuecomment-1860589421.
In 6.1.3, the @RequestBody
resolver correctly defers to method validation, and that results in a MethodValidationException
with validation errors for all parameters. The actual issue to resolve here is a missing feature in Spring Boot's error response support that wasn't noticed until now. I've created https://github.com/spring-projects/spring-boot/issues/39858.
In the mean time, as of Spring Framework 6.0 we have enhanced support for RFC 7807 error responses, and ResponseEntityExceptionHandler
(included with spring.mvc.problemdetails.enabled
) to render error responses with details. The Boot error responses are really meant to be more of a fallback for unresolved errors, but historically we lacked a concrete format for error responses. The RFC 7807 response support provides more control over the details of validation and binding result messages via ResourceBundle's, or via code if necessary (e.g. overriding methods in ResponseEntityExceptionHandler
), and HandlerMethodValidationException
has a Visitor
to render validation errors by parameter type, see the Validation section.
Comment From: notizklotz
Thanks a lot for your elaborate answer!
Comment From: simonzhong1985
@notizklotz what should we do to get error details as for HandlerMethodValidationException? thanks.