在Spring中,我们可以使用@Valid注解对实体进行校验。在Controller的方法参数中添加@Valid注解,然后在实体类的属性上添加校验注解,例如@NotNull、@Size等。例如:
@RestController public class UserController { @PostMapping("/users") public ResponseEntitycreateUser(@Valid @RequestBody User user) { userService.createUser(user); return new ResponseEntity<>(user, HttpStatus.CREATED); } }
在这个例子中,我们使用@Valid注解对User实体进行校验,并在User类的属性上添加了@NotNull和@Size注解。当请求到达Controller时,Spring会自动对User实体进行校验,如果校验失败则会抛出MethodArgumentNotValidException异常。我们可以使用@ControllerAdvice和@ExceptionHandler来处理校验异常,并返回自定义的错误信息。例如:
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntityhandleValidationException(MethodArgumentNotValidException ex) { BindingResult result = ex.getBindingResult(); List fieldErrors = result.getFieldErrors(); List errors = new ArrayList<>(); for (FieldError fieldError : fieldErrors) { errors.add(fieldError.getField() + ": " + fieldError.getDefaultMessage()); } ErrorResponse errorResponse = new ErrorResponse(HttpStatus.BAD_REQUEST, "Validation failed", errors); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); } }
在这个例子中,我们使用@ControllerAdvice注解来定义全局的异常处理器,并使用@ExceptionHandler注解来处理MethodArgumentNotValidException异常。在处理过程中,我们从异常中获取校验结果并转换成自定义的错误信息,然后封装成ErrorResponse对象并返回。如果请求中包含了校验错误,Spring会自动调用该处理器并返回错误信息。
@Valid和@Validated注解都可以用于实体类属性的校验。它们的主要区别在于支持的校验分组和校验器的不同。
@Valid注解只支持默认分组,即没有使用任何分组的校验注解。它使用的是javax.validation包下的校验器。
@Validated注解支持分组校验,即可以使用指定分组的校验注解进行校验。它使用的是Spring自己的校验器,支持JSR-303和JSR-349规范。
此外@Validated 注解还可以用于方法级别的校验,例如:
@Service public class UserService { @Validated public void createUser(@NotNull User user) { //... } }
在这个例子中,我们使用@Validated注解对createUser方法进行校验,并使用@NotNull注解对User参数进行非空校验。如果校验失败,Spring会抛出ConstraintViolationException异常。
简单理解:
在Spring中,我们可以使用@NotBlank注解对字符串进行非空校验。在实体类的属性上添加@NotBlank注解即可。例如:
public class User { @NotBlank private String username; //... }
在这个例子中,我们使用@NotBlank注解对username属性进行非空校验。当请求到达Controller时,Spring会自动对User实体进行校验,如果校验失败则会抛出MethodArgumentNotValidException异常。
深入理解:
在Spring中,在方法执行前执行校验注解的过程是由MethodValidationInterceptor
拦截器实现的。这个拦截器会在方法调用前执行校验注解,如果校验失败会抛出异常。在拦截器中,会先获取方法上的校验注解,然后根据注解的类型,调用不同的校验器进行校验。如果校验失败,会抛出ConstraintViolationException异常。
MethodValidationInterceptor
会被Spring的其中一个BeanPostProcessor: MethodValidationPostProcessor
在Bean初始化时作为默认的方法校验增强器进行创建。
整体理解:
当Spring框架在执行方法时,会先查找是否存在MethodValidationPostProcessor后置处理器。如果存在,它会在方法执行之前执行校验注解的过程。
MethodValidationPostProcessor后置处理器会在BeanPostProcessor的postProcessBeforeInitialization方法中执行,具体流程如下:
综上所述,Spring解析@Valid的过程主要涉及到MethodValidationPostProcessor后置处理器,在BeanPostProcessor的postProcessBeforeInitialization方法中生成代理对象,并在方法执行前执行校验注解的过程。
org.springframework.boot
spring-boot-starter-validation
2.7.10
spring-boot-starter-logging
org.springframework.boot
org.springframework.boot
spring-boot-starter
如果是SpringBoot项目需要注意判断是否已经存在必须的依赖 spring-boot-starter-validation
,注意如果Spring-boot的版本大于3.0必须最第使用JDK17。上面的依赖版本是3.0以下可用的最高版本。