Spring Boot MVC-我们需要在绑定结果中使用@Valid吗?

时间:2019-07-19 06:26:10

标签: spring-boot spring-mvc binding

我正在使用带有绑定结果示例的Spring Boot + Spring Data JPA。我有将近100个控制器,对于每个“创建/更新请求”,我们在下面进行操作。

@PostMapping
public ResponseEntity<HttpStatus> saveStudent(@Valid @RequestBody StudentDto dto, BindingResult br){
    if (br.hasErrors()) {
        throw new InvalidRequestException("Wrong resource", br);
    }

    divisionService.saveStudent(dto);
    return new ResponseEntity<>(HttpStatus.CREATED);
}

是否可以将这一逻辑集中在一个地方?我们可以为同一个开发听众吗?

if (br.hasErrors()) {
    throw new InvalidRequestException("Wrong resource", br);
}

1 个答案:

答案 0 :(得分:0)

您不需要在控制器中引用BindingResult

如果您想基于某些自定义逻辑是否有错误(例如,错误),只需在控制器中引用BindingResult。重定向到Rest API方案中的其他视图。

Java Bean Validation框架将抛出​​验证异常(通过 您@Valid注释)或适用于该请求的任何Spring Validator实现。

对于后一种情况,框架会抛出MethodArgumentNotValidException,因此您只需创建一个ControllerAdvice(https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc)实现即可处理此类型的异常,并且可以从中获取BindingResult

@ControllerAdvice
public class ValidationErrorHandlingAdvice {

    /**
     * Handler for {@link MethodArgumentNotValidException}s. These are triggered by
     * Spring {@link Validator} implementations being invoked by the Spring MVC
     * controllers and returning validation errors.
     * 
     * 
     * @param ex The {@link MethodArgumentNotValidException} to be handled.
     * 
     * @return {@link Map} keyed by field to which the error is bound and with the
     *         value of the field as a value.
     */
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public @ResponseBody ValidationErrors handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        Map<String, List<String>> errorMap = new TreeMap<>();

        BindingResult result = ex.getBindingResult();
        for (FieldError error : result.getFieldErrors()) {

            if (!errorMap.containsKey(error.getField())) {
                errorMap.put(error.getField(), new ArrayList<String>());
            }

            errorMap.get(error.getField()).add(error.getDefaultMessage());
        }

        return new ValidationErrors(errorMap);
    }


    private static class ValidationErrors {
        private Map<String, List<String>> errors;

        public ValidationErrors(Map<String, List<String>> errors) {
            this.errors = errors;
        }

        @SuppressWarnings("unused")
        public Map<String, List<String>> getErrors() {
            return errors;
        }
    }
}