Lingmoumou's Blog

きっといつかって愿うまま

0%

自定义Hibenate Validator

Spring中使用@vaild 注解进行验证传过来的参数校验,然后通过统一异常处理。如@not null、@not blank、@not empty、@Email等等。但是实际业务中可能默认提供的注解不够用,因此需要自定义验证注解。

MyConstraintValidator.java

实现ConstraintValidator接口,它有两个泛型,如上图

  1. 自定义的注解类,
  2. 要验证的数据的类型(例如写了String类型的数据,那么这个注解就要放在String类型的字段上才会起作用,若写成Object,那么它可以接收任何数据类型的数据)。
  3. initialize是初始化方法;
  4. isValid为验证的逻辑方法,返回true,则验证通过,否则不通过。

在这个实现中,可以用@Autowire注入需要的类。

MyConstraint需要有message()、groups()、payload()三个属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// MyConstraint.java
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {

String message() default "MyConstraint default msg";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}

// MyConstraintValidator.java
public class MyConstraintValidator implements ConstraintValidator<MyConstraint,Object> {

@Autowired
private HelloService helloService;

@Override
public void initialize(MyConstraint constraintAnnotation) {
System.out.println("my validator init");
}

@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
helloService.greeting("tom");
System.out.println(value);
return false;
}
}

// User.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

private int id;

@MyConstraint(message = "这是一个测试")
private String username;

@NotBlank(message = "密码不能为空")
private String password;

@Past(message = "生日必须是过去的时间")
private Date birthday;

}

@Target

注解的作用目标

  • @Target(ElementType.TYPE):接口、类、枚举、注解
  • @Target(ElementType.FIELD):字段、枚举的常量
  • @Target(ElementType.METHOD):方法
  • @Target(ElementType.PARAMETER):方法参数
  • @Target(ElementType.CONSTRUCTOR):构造函数
  • @Target(ElementType.LOCAL_VARIABLE):局部变量
  • @Target(ElementType.ANNOTATION_TYPE):注解
  • @Target(ElementType.PACKAGE):包

@Retention

注解的保留位置

  • RetentionPolicy.SOURCE: 这种类型的Annotations只在源代码级别保留,编译时就会被忽略,在class字节码文件中不包含。
  • RetentionPolicy.CLASS: 这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得。
  • RetentionPolicy.RUNTIME: 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。

@Constraint

来限定自定义注解的方法
@Constraint(validatedBy = MyConstraintValidator.class)
@Constraint(validatedBy = {MyConstraintValidator.StringChecker.class, MyConstraintValidator.LongChecker.class})
可以代表一个或者多个校验处理逻辑。

@Document

说明该注解将被包含在javadoc中

@Inherited

说明子类可以继承父类中的该注解