JOH*_*HND 10 java validation spring jsr bean-validation
当我在 javax.validations 中使用 @valid 注释验证 bean 时,对于某些对象,我收到 ConstraintViolationException,而对于某些对象,我收到 MethodArgumentNotValidException。
我明白,如果我在 controller 处验证 @ResponseBody 中的任何内容,它会抛出 MethodArgumentNotValidException。
但是对于类级别的某些自定义验证(例如@MyCustomValidation),即使在@ResponseValidation 中对其进行验证,它也会抛出ConstraintViolationException。
对于不同 REST 端点的其他一些自定义验证,它会抛出 MethodArgumentNotValidException。
我发现它有点难以理解,因为它是一种行为。
@PostMapping(path = "/someEndPoint")
@Validated(OnASave.class)
public ResponseEntity<ClassA> saveObjA(@Valid @RequestBody ClassA objA)
Run Code Online (Sandbox Code Playgroud)
结果 - 抛出 MethodArgumentNotValidException
@PostMapping(path = "/someOtherEndPoint")
@Validated(OnBSave.class)
public ResponseEntity<ClassB> saveObjB(@Valid @RequestBody ClassB objB)
Run Code Online (Sandbox Code Playgroud)
结果 - 抛出 ConstraintViolationException
ClassA 和 ClassB 都有自定义验证。
小智 15
为了简单理解,如果使用注释在控制器/服务层进行验证@Valid,则会生成MethodArgumentNotValidException. 您可以为此添加一个处理程序并相应地返回响应。该类是Spring框架的一部分,验证由Spring框架执行。请参阅下面的示例:
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Response> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
logger.info("Invalid arguments found : " + ex.getMessage());
// Get the error messages for invalid fields
List<FieldError> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(fieldError -> new FieldError(fieldError.getField(), fieldError.getDefaultMessage()))
.collect(Collectors.toList());
String message = messageSource.getMessage("invalid.data.message", null, LocaleContextHolder.getLocale());
Response response = new Response(false, message)
.setErrors(errors);
ResponseEntity<Response> responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
return responseEntity;
}
Run Code Online (Sandbox Code Playgroud)
相反,如果您不使用@Valid注释进行验证,Hibernate 将在 JPA 层引发异常并生成ConstraintViolationException. 此异常是 Javax bean 验证框架的一部分,并在执行持久性操作时(在实际 SQL 执行之前)引发。请参阅下面的示例:
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Response> handleConstraintViolationException(ConstraintViolationException ex) {
List<FieldError> errors = ex.getConstraintViolations()
.stream()
.map(constraintViolation -> {
return new FieldError(constraintViolation.getRootBeanClass().getName() + " " + constraintViolation.getPropertyPath(), constraintViolation.getMessage());
})
.collect(Collectors.toList());
String message = messageSource.getMessage("invalid.data.message", null, LocaleContextHolder.getLocale());
Response response = new Response(false, message)
.setErrors(errors);
ResponseEntity<Response> responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
return responseEntity;
}
Run Code Online (Sandbox Code Playgroud)
当您使用@Valid 时,您正在应用您在模型类字段上定义的验证,而验证有不同类型,您可以选择@NotNull、@Max、@Min 等,您将获得匹配类型。
通常,所有这些都与MethodArgumentNotValidException并行,在所有情况下都会抛出MethodArgumentNotValidException。
来自官方文档
当对用 @Valid 注释的参数的验证失败时抛出的异常。
当违反某些约束时,休眠实体管理器会抛出 ConstraintViolationException,因此这意味着您违反了正在使用的某些实体中的某些字段。
| 归档时间: |
|
| 查看次数: |
4579 次 |
| 最近记录: |