Java中@valid和@Validated注解的使用详解
作者:Mu_Mu是一只小白
这篇文章主要介绍了Java中@valid和@Validated注解的使用详解,@Validated可以用在类型、方法和方法参数上,但是不能用在成员属性(字段)上,不支持嵌套检测,@Valid可以用在方法、构造函数、方法参数和成员属性(字段)上,支持嵌套检测,需要的朋友可以参考下
1.简介
- @Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上,不支持嵌套检测
- @Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上,支持嵌套检测
2.引入maven
springboot 2.3.0 以后不会自动引入jar包,所以要添加以下maven,2.3以前则不需要引入maven包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
3.配合使用注解
- @Null 限制只能为null
- @NotNull 限制必须不为null
- @AssertFalse 限制必须为false
- @AssertTrue 限制必须为true
- @DecimalMax(value) 限制必须为一个不大于指定值的数字
- @DecimalMin(value) 限制必须为一个不小于指定值的数字
- @Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
- @Future 限制必须是一个将来的日期
- @Max(value) 限制必须为一个不大于指定值的数字
- @Min(value) 限制必须为一个不小于指定值的数字
- @Past 限制必须是一个过去的日期
- @Pattern(value) 限制必须符合指定的正则表达式
- @Size(max,min) 限制字符长度必须在min到max之间
- @Past 验证注解的元素值(日期类型)比当前时间早
- @NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
- @NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
- @Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
4.例子
4.1 model
@Valid 定义schoole属性是为了实现嵌套验证,没有这个注解无法校验school类内部需要校验的属性。
public class UserVO { @NotNull(message = "id不能为空。" ,groups = {Insert.class}) private Integer id; @NotBlank(message = "name不能为空。",groups = {Update.class}) private String name; @NotNull(message = "schoole不能为空。") @Valid private Schoole schoole; @Min(value = 1,message = "age不能小于1") @Max(value = 130,message = "age不能大于130") private int age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Schoole getSchoole() { return schoole; } public void setSchoole(Schoole schoole) { this.schoole = schoole; }
public class Schoole { @NotBlank(message = "name不能为空。",groups = {Update.class}) private String name; @NotNull(message = "id不能为空") private Integer id; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; }
4.2分组接口
实现Default 接口,不然@Validated({Update.class}) 使用Update分组时,未定义分组的默认校验属性不会生效(比如校验schoole的 @NotNull(message = “schoole不能为空。”))
import javax.validation.groups.Default; public interface Insert extends Default { } public interface Update extends Default { }
4.3controller
@Validated 标明group 时(Update.class)只有需要校验属性上校验注解含有该接口(Update.class)才生效,如果group (Update.class)实现了Default接口那么需要校验属性上的校验注解未定义任何group 时也会生效。
@RestController @RequestMapping("/valid") public class TestValidController { private static final Logger LOG = LoggerFactory.getLogger(TestValidController.class); @RequestMapping("/test") public void testValid(@Validated({Update.class}) UserVO userVO){ LOG.info("userVo:"+userVO); } @PostMapping("/test2") public void testValid2(@Validated() @RequestBody UserVO userVO){ LOG.info("userVo:"+userVO); } }
4.3.1 基本数据类型校验
需要在类上加@Validated,然后方法直接使用@NotNull等校验注解
@Validated public class HrmEmployeeContractController { @Resource private IHrmEmployeeContractService contractService; @GetMapping("/listByEmployeeId2") public ResponseUtil listByEmployeeId2( @NotNull(message = "employeeId 不能为空") Long employeeId) { return ResponseUtil.success(contractService.list(Wrappers.<HrmEmployeeContract>lambdaQuery() .eq(HrmEmployeeContract::getEmployeeId, employeeId) .eq(HrmEmployeeContract::getDeleted, DataStatusEnum.ENABLE.getType()))); } }
4.4使用全局异常拦截器拦截参数校验异常
MethodArgumentNotValidException异常由@RequestBody 修饰的参数未校验过抛出,其他未校验通过抛出异常BindException。
@RestControllerAdvice public class GlobalExceptionHandler { private Logger LOG= LoggerFactory.getLogger(GlobalExceptionHandler.class); //BindException 校验参数不满足条件抛出 @ExceptionHandler(BindException.class) public Object handleValidException(BindException e) { return ResponseUtil.fail(400,e.getBindingResult().getFieldError().getDefaultMessage()); } //MethodArgumentNotValidException @RequestBody 修饰的参数未校验过抛出 @ExceptionHandler(MethodArgumentNotValidException.class) public Object handleValidException2(MethodArgumentNotValidException e) { return ResponseUtil.fail(400,e.getBindingResult().getFieldError().getDefaultMessage()); } @ExceptionHandler(RuntimeException.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public ResponseUtil handleRuntimeException(RuntimeException ex) { int code = 500; String message = ex.getMessage(); LOG.error(ex.getMessage(), ex); return ResponseUtil.fail(code,message); } @ExceptionHandler(Exception.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public ResponseUtil handleException(Exception ex) { int code = 500; String message = ex.getMessage(); LOG.error(ex.getMessage(), ex); return ResponseUtil.fail(code,message); } }
测试
结果:
Schoole 里面的id 每天报id不能为空
spring Validation 默认会校验完所有字段,然后抛异常,可以配置快速失败,一旦校验失败立马抛异常。
@Bean public Validator validator(){ ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure() .failFast(true) .buildValidatorFactory(); return validatorFactory.getValidator(); }
到此这篇关于Java中@valid和@Validated注解的使用详解的文章就介绍到这了,更多相关@valid和@Validated注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!