For a simple RESTful JSON api implemented in Spring MVC, can I use Bean Validation (JSR-303) to validate the path variables passed into the handler method?
For example:
@RequestMapping(value = "/number/{customerNumber}") @ResponseBody public ResponseObject searchByNumber(@PathVariable("customerNumber") String customerNumber) { ... }
Here, I need to validate the customerNumber variables's length using Bean validation. Is this possible with Spring MVC v3.x.x? If not, what's the best approach for this type of validations?
Thanks.
Validating a PathVariable Let's consider an example where we validate that a String parameter isn't blank and has a length of less than or equal to 10: @GetMapping("/valid-name/{name}") public void createUsername(@PathVariable("name") @NotBlank @Size(max = 10) String username) { // ... }
@PathVariable is a Spring annotation which indicates that a method parameter should be bound to a URI template variable. If the method parameter is Map<String, String> then the map is populated with all path variable names and values. It has the following optional elements: name - name of the path variable to bind to.
Validate Request parameter When creating a route with Spring, adding an annotation rule to validate the input is possible. In our case, we will apply a Regex the validate the format of the reservation's code. Now run the application and test with a bad reservation code. Launch the application and test.
Spring does not support @javax.validation.Valid
on @PathVariable
annotated parameters in handler methods. There was an Improvement request, but it is still unresolved.
Your best bet is to just do your custom validation in the handler method body or consider using org.springframework.validation.annotation.Validated
as suggested in other answers.
You can use like this: use org.springframework.validation.annotation.Validated
to valid RequestParam
or PathVariable
.
* * Variant of JSR-303's {@link javax.validation.Valid}, supporting the * specification of validation groups. Designed for convenient use with * Spring's JSR-303 support but not JSR-303 specific. *
step.1 init ValidationConfig
@Configuration public class ValidationConfig { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor processor = new MethodValidationPostProcessor(); return processor; } }
step.2 Add @Validated
to your controller handler class, Like:
@RequestMapping(value = "poo/foo") @Validated public class FooController { ... }
step.3 Add validators
to your handler method:
@RequestMapping(value = "{id}", method = RequestMethod.DELETE) public ResponseEntity<Foo> delete( @PathVariable("id") @Size(min = 1) @CustomerValidator int id) throws RestException { // do something return new ResponseEntity(HttpStatus.OK); }
final step. Add exception resolver to your context:
@Component public class BindExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { if (ex.getClass().equals(BindException.class)) { BindException exception = (BindException) ex; List<FieldError> fieldErrors = exception.getFieldErrors(); return new ModelAndView(new MappingJackson2JsonView(), buildErrorModel(request, response, fieldErrors)); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With