环境准备
在项目中添加以下依赖
maven
1 | <dependency> |
spring配置文件中增加1
<mvc:annotation-driven />
常用的校验注解示例
1 | //该参数必须为空 |
校验类方法中的自定义对象
- 在参数上加@Valid,(或者加@Validated也是可以的)
- 在自定义对象中的属性上加上校验注解
1
2
3
4
5
6
7
8
9
10
11
12
public String hello( User user , BindingResult bindingResult){
if(bindingResult.hasErrors()) {
StringBuffer sb = new StringBuffer();
for (ObjectError objectError : bindingResult.getAllErrors()) {
sb.append(((FieldError) objectError).getField() + " : ").append(objectError.getDefaultMessage());
}
System.out.println(sb.toString());
}
return "hello";
}1
2
3
4
5
6
7
8
9
10public class User {
int id;
String name;
//setter getter ....
}
关于@Valid和@Validated的区别联系
一直对@Valid和@Validated这两个注解非常疑惑,不知道怎么区分和使用。
- 包位置
- @Valid: javax.validation, 是javax,也是就是jsr303中定义的规范注解
- @Validated: org.springframework.validation.annotation, 是spring自己封装的注解。
- 功能
- @Valid就不用说了,是jsr303的规范。
- @Validated是@Valid的一个变种,扩展了@Valid的功能,支持group分组校验的写法。
那么我们对于@Valid和@Validated就可以这么理解:
- 能用@Valid的地方通常可以用@Validated替代。
- 需要使用分组校验的时候使用@Validated注解
分组校验
我们有一个用户DTO,其中有id,username两个属性。当保存时,id不需要有值,由数据库自动生成,我们使用@Null注解校验。当更新时,id需要有值,根据ID去更新用户名,我们使用@NotNull注解校验。无论是保存用户还是更新用户,都需要校验用户名,我们使用@NotBlank注解校验。
1 | public interface SaveGroup { |
定义相应类型的公开接口(SaveGroup,UpdateGroup),给每个校验注解指定groups属性,如果不指定则默认为javax.validation.groups.Default.class。
我们让SaveGroup和UpdateGroup继承了Default, 那么三个接口之间的关系类似如下:
1 | save --> SaveGroup |-->id @Null |
1 |
|
在方法参数的对象上加@Validated属性,填写Value为对应的接口的class即可,这时候访问不同的接口就会进行不同的校验了。
自定义校验注解
有时候默认提供的校验注解无法满足我们的需要,我们需要自定义。例如现有校验注解不支持java8中的LocalDateTime。那么接下来我们自定义一个校验LocalDateTime的注解。该注解判断传入的时间是否是一个过去的时间。
- 创建校验注解
- 编写校验规则 校验规则也就是枚举PastDate中指定的validateBy属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
*
*/
public PastDate {
String message();
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}1
2
3
4
5
6
7
8
9
10
11
12public class PastTimeValidate implements ConstraintValidator<PastDate, LocalDateTime> {
public void initialize(PastDate constraintAnnotation) {
log.info("init enum PastDate");
}
public boolean isValid(LocalDateTime localDateTime, ConstraintValidatorContext context) {
return localDateTime.isBefore(LocalDateTime.now()) ? true : false;
}
}
写完这些,我们就可以像@Past对Date校验一样使用@PastDate对LocalDateTime进行校验了。