BindingResult hasErrors()不生效,每次返回相同结果的技术求助
问题原因
当使用@RequestBody接收JSON格式参数时,Spring默认不会将校验错误自动绑定到BindingResult中。这是因为@RequestBody的参数解析由HttpMessageConverter(如Jackson)完成,而普通表单参数的校验是通过WebDataBinder处理,后者才会自动将错误填充到BindingResult。所以你直接把BindingResult跟在@RequestBody参数后,它始终是空的,hasErrors()自然一直返回false。
解决方案
前提:确保实体类添加校验注解
首先要在Employee类的字段上添加JSR-380校验注解(需引入spring-boot-starter-validation依赖),示例如下:
public class Employee { @NotNull(message = "员工ID不能为空") private Long id; @Size(min = 2, max = 20, message = "姓名长度需在2-20字符之间") private String name; // getter、setter方法 }
方案一:使用@Valid配合全局异常捕获(推荐)
这种方式符合Spring最佳实践,通过全局异常处理器统一处理校验错误:
@RequestMapping(value = "/submit", method = RequestMethod.POST) public ResponseEntity<?> submit(@Valid @RequestBody Employee employee) throws EmployeeNotFoundException { return new ResponseEntity<>(employeeRepository.save(employee), HttpStatus.CREATED); } // 全局异常处理器 @RestControllerAdvice public class GlobalValidationExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<?> handleValidationErrors(MethodArgumentNotValidException ex) { List<String> errorMessages = ex.getBindingResult() .getFieldErrors() .stream() .map(error -> String.format("%s: %s", error.getField(), error.getDefaultMessage())) .collect(Collectors.toList()); return new ResponseEntity<>(errorMessages, HttpStatus.CONFLICT); } }
当Employee的字段不符合校验规则时,Spring会抛出MethodArgumentNotValidException,全局处理器捕获后提取错误信息返回。
方案二:手动触发校验并绑定到BindingResult
如果坚持要使用BindingResult处理,可以手动调用Validator完成校验,并将错误添加到BindingResult中:
@RequestMapping(value = "/submit", method = RequestMethod.POST) public ResponseEntity<?> submit(@RequestBody Employee employee, BindingResult bindingResult) throws EmployeeNotFoundException { // 获取默认Validator Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); Set<ConstraintViolation<Employee>> violations = validator.validate(employee); // 将校验错误绑定到BindingResult for (ConstraintViolation<Employee> violation : violations) { String fieldName = violation.getPropertyPath().toString(); String errorMsg = violation.getMessage(); bindingResult.addError(new FieldError("employee", fieldName, errorMsg)); } if (!bindingResult.hasErrors()) { return new ResponseEntity<>(employeeRepository.save(employee), HttpStatus.CREATED); } else { List<String> errorMessages = bindingResult.getFieldErrors() .stream() .map(error -> String.format("%s: %s", error.getField(), error.getDefaultMessage())) .collect(Collectors.toList()); return new ResponseEntity<>(errorMessages, HttpStatus.CONFLICT); } }
内容的提问来源于stack exchange,提问作者DeadSilent
相关产品推荐
相关产品推荐

