Spring boot, how to use @Valid with List<T>

一世执手 提交于 2019-12-05 18:33:24

问题


I am trying to put validation to a Spring Boot project. So I put @NotNull annotation to Entity fields. In controller I check 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, "");
}

This works. But when I make it with input 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, what I want is to apply validation check like in the add method to each Status object in the requestbody list. So, the sender will now which objects have fault and which has not.

How can I do this in a simple, fast way?


回答1:


My immediate suggestion is to wrap the List in another POJO bean. And use that as the request body parameter.

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 did not try it though.

Update: The accepted answer in this SO link gives a good explanation why bean validation are not supported on Lists.




回答2:


Just mark controller with @Validated annotation.

It will throw ConstraintViolationException, so probably you will want to map 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;
    }
}



回答3:


@RestController
@Validated
@RequestMapping("/products")
    public class ProductController {
        @PostMapping
        @Validated(MyGroup.class)
        public ResponseEntity<List<Product>> createProducts(
            @RequestBody List<@Valid Product> products
        ) throws Exception {
            ....
        }
}


来源:https://stackoverflow.com/questions/39348234/spring-boot-how-to-use-valid-with-listt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!