Spring boot how to use @Valid with <T> list
I am trying to put validation in a Spring boot project. So I put the @NotNull annotation in the Entity fields. In the controller, I test it like this:
@RequestMapping(value="", method = RequestMethod.POST) public DataResponse add(@RequestBody @Valid Status status, BindingResult bindingResult) { if(bindingResult.hasErrors()) { return new DataResponse(false, bindingResult.toString()); } statusService.add(status); return new DataResponse(true, ""); } It works. But when I do this with the input of List<Status> statuses , it doesn't work.
@RequestMapping(value="/bulk", method = RequestMethod.POST) public List<DataResponse> bulkAdd(@RequestBody @Valid List<Status> statuses, BindingResult bindingResult) { // some code here } Basically, I want to apply validation validation, as in the add method, for each state object in the request list. So, the sender will now, which objects have an error and which do not.
How can I do this in a simple, quick way?
My immediate suggestion is to wrap the list in another POJO bean. And use this as a parameter to the request body.
In your example.
@RequestMapping(value="/bulk", method = RequestMethod.POST) public List<DataResponse> bulkAdd(@RequestBody @Valid StatusList statusList, BindingResult bindingResult) { // some code here } and StatusList.java will be
@Valid private List<Status> statuses; //Getter //Setter //Constructors I have not tried, though.
Update: The accepted answer in this SO link gives a good explanation of why bean validation is not supported in lists.
Just tick the @Validated annotation controller.
It will throw a ConstraintViolationException , so you probably want to match it to 400: BAD_REQUEST :
import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice(annotations = Validated.class) public class ValidatedExceptionHandler { @ExceptionHandler public ResponseEntity<Object> handle(ConstraintViolationException exception) { List<String> errors = exception.getConstraintViolations() .stream() .map(this::toString) .collect(Collectors.toList()); return new ResponseEntity<>(new ErrorResponseBody(exception.getLocalizedMessage(), errors), HttpStatus.BAD_REQUEST); } private String toString(ConstraintViolation<?> violation) { return Formatter.format("{} {}: {}", violation.getRootBeanClass().getName(), violation.getPropertyPath(), violation.getMessage()); } public static class ErrorResponseBody { private String message; private List<String> errors; } }