Problem
One can’t use validation annotations on @PathVariable
annotations with i.e. @Pattern
annotation like this:
@RequestMapping(value = "/bank/{id}", method = RequestMethod.GET) public ResponseEntity method_name( @Pattern(regexp = "\\d{9}", message = "Bank shoud be identified by exactly 9 digits") @PathVariable String id) { /// Some code }
Solution
For validation to work we should make a few things
Declare method validation bean
In one of your @Configuration
classes you should declare @Bean
of type MethodValidationPostProcessor
@Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); }
MethodValidationPostProcessor:
A convenient
BeanPostProcessor
implementation that delegates to a JSR-303 provider for performing method-level validation on annotated methods.Target classes with such annotated methods need to be annotated with Spring’s
Validated
annotation at the type level, for their methods to be searched for inline constraint annotations. Validation groups can be specified through@Validated
as well. By default, JSR-303 will validate against its default group only.
Create exception handler
Declare @ControllerAdvice
-annotated class with @ExceptionHandler
-annotated method inside
@ControllerAdvice class GlobalExceptionHandler { @ExceptionHandler(value = { ConstraintViolationException.class }) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public String handle(ConstraintViolationException e) { Set<ConstraintViolation<?>> violations = e.getConstraintViolations(); StringBuilder strBuilder = new StringBuilder(); for (ConstraintViolation<?> violation : violations ) { strBuilder.append(violation.getMessage() + "\n"); } return strBuilder.toString(); } }
Several important lines:
- 1:
@ControllerAdvice
annotation on class - 3: declaration of `@ExceptionHandler` for `ConstraintViolationException`
- 4: declaration of status, which will be returned (as usual it’s considered to be a good practice to return `HttpStatus.BAD_REQUEST` on requests with wrong attributes)
- 5: declaration of method, capable of handling `ConstraintViolationException`
Add validation annotation on controller
@Validated @RestController class BankController { @RequestMapping(value = "/bank/{id}", method = RequestMethod.GET) public ResponseEntity<BankInfo> bankInfo( @Pattern(regexp = "\\d{9}", message = "Bank shoud be identified by exactly 9 digits") @PathVariable String id) { /// Some code } }
Add @Validated
annotation to your controller class for PostProcessor to be able to handle requests to your method.