引入Hibernate校验依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
代码实现校验
- 在实体类属性上标注校验注解
@Data
public class LoginVo {
@NotEmpty
private String username;
@NotEmpty(message = "密码不能为空")
private String password;
@Length(min = 4,max = 4,message = "验证码长度为4位")
private String captcha;
}
其他功能校验注解如下:
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
@NotBlank(message =) 验证字符串非null,且trim后长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
@AssertFalse 校验false
@AssertTrue 校验true
@DecimalMax(value=,inclusive=) 小于等于value,
inclusive=true,是小于等于
@DecimalMin(value=,inclusive=) 与上类似
@Max(value=) 小于等于value
@Min(value=) 大于等于value
@NotNull 检查Null
@Past 检查日期
@Pattern(regex=,flag=) 正则
@Size(min=, max=) 字符串,集合,map限制大小
@Valid 对po实体类进行校验
- 在controller层方法上的参数位置添加校验注解
@GetMapping("login")
public String login(@RequestBody @Validated LoginVo loginVo){
System.out.println(loginVo);
return "ok";
}
此时如果校验不通过会抛出MethodArgumentNotValidException异常,通过编写全局异常处理器来处理该校验异常
@org.springframework.web.bind.annotation.RestControllerAdvice
public class GlobalRestControllerAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
public String methodArgumentNotValidException(MethodArgumentNotValidException e){
List<FieldError> fieldErrors = e.getFieldErrors();
StringBuffer sb = new StringBuffer();
for (FieldError fieldError : fieldErrors) {
String defaultMessage = fieldError.getDefaultMessage();
sb.append(defaultMessage).append(",");
}
return sb.toString();
}
}
校验组的使用
在校验时某些字段并不是特定的为空或者不为空,例如修改逻辑,当修改某一条数据时,会需要该条数据携带id,id属性不能为空,此时如果在id属性上面标注@NotEmpty注解在修改时是没问题的,但是如果是新增呢?新增时需要后端生成id,所以此时前端不能携带id,那么就会校验不通过,这种情况就和我们的业务逻辑相矛盾了。此时JSR303提出了校验组的理念,就是在校验某个对象时,只校验符合本次校验组的属性。
- 定义一个校验组(随便一个类就可以,只是一个标识作用)
public interface UserLoginGroup {
}
- 在@Validate注解中标识只校验该组的属性
@GetMapping("login")
public String login(@RequestBody @Validated(value = UserLoginGroup.class) LoginVo loginVo){
System.out.println(loginVo);
return "ok";
}
- 在实体类属性的校验注解中指定校验组
@NotEmpty(message = "密码不能为空",groups = UserLoginGroup.class)
private String password;
此时只会校验匹配@Validate注解的校验组的属性。但是这样也是存在一个缺点,因为绝大部分属性是新增和修改时都需要校验,那么这个时候就需要在属性上写俩校验组,这就造成代码冗余了。这种特殊的属性如id单独校验一下即可。