Description:
In a Spring MVC REST Controller, when a cross-parameter validation constraint (annotated with @SupportedValidationTarget(ValidationTarget.PARAMETERS)) is applied to a method, the validation fails to interrupt the request flow if spring.validation.method.adapt-constraint-violations is set to true.
The validator is correctly invoked and returns false, but no exception is triggered, and the controller method is executed anyway.
Analysis:
The issue resides in how MethodValidator handles the MethodValidationResult.
When a cross-parameter constraint fails, result.getParameterValidationResults() is empty, while result.getCrossParameterValidationResults() contains the violations.
However, the current logic only seems to trigger an exception based on individual parameter results.
Specifically, in the current Spring Framework 6.2.15 source MethodValidator#applyArgumentValidation, the MethodValidationException is triggered only when result.getParameterValidationResults() is not empty (checked through result.hasError()), the method applyArgumentValidation never check result.getCrossParameterValidationResults().
Steps to reproduce:
- Create a REST Controller with a method-level cross-parameter constraint.
- Set
spring.validation.method.adapt-constraint-violations=true in application.yml.
- Invoke the endpoint with arguments that trigger a validation failure.
- Observed: The controller method is executed (returns HTTP 200).
- Expected: A
MethodValidationException should be thrown before the controller method is invoked.
Please see https://github.com/zerikv/spring-issue-36666, this repo contains a minimal spring-boot project which reproduce the problem.
Environment:
- Spring Boot: 3.5.10
- Spring Framework: 6.2.15
- JDK: 21
Description:
In a Spring MVC REST Controller, when a cross-parameter validation constraint (annotated with
@SupportedValidationTarget(ValidationTarget.PARAMETERS)) is applied to a method, the validation fails to interrupt the request flow ifspring.validation.method.adapt-constraint-violationsis set totrue.The validator is correctly invoked and returns
false, but no exception is triggered, and the controller method is executed anyway.Analysis:
The issue resides in how
MethodValidatorhandles theMethodValidationResult.When a cross-parameter constraint fails,
result.getParameterValidationResults()is empty, whileresult.getCrossParameterValidationResults()contains the violations.However, the current logic only seems to trigger an exception based on individual parameter results.
Specifically, in the current Spring Framework 6.2.15 source
MethodValidator#applyArgumentValidation, theMethodValidationExceptionis triggered only whenresult.getParameterValidationResults()is not empty (checked throughresult.hasError()), the methodapplyArgumentValidationnever checkresult.getCrossParameterValidationResults().Steps to reproduce:
spring.validation.method.adapt-constraint-violations=trueinapplication.yml.MethodValidationExceptionshould be thrown before the controller method is invoked.Please see https://github.com/zerikv/spring-issue-36666, this repo contains a minimal spring-boot project which reproduce the problem.
Environment: