javax.validation.* 包下提供了部分现成的API可供参数校验使用,但并不能完全满足我们的需求。
validation [,vælɪ'deɪʃən] 确认;批准;验证
constraint [kən'streint] 约束;限制;约束条件
1. 导入依赖。
2. 自定义验证注解。
3. 创建自定义注解验证器。
4. 使用自定义注解修饰对象。
5. 在需要检验的地方加入@Valid注解声明。
javax.validation validation-api
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = StudentAgeValidator.class) public @interface AgeBetween { String message() default "Not in line with the student's age"; int min() default 0; int max() default 30; Class>[] groups() default {}; Class extends Payload>[] payload() default {}; }
注解说明:
@Target指明这个注解要作用在什么地方,可以是对象、域、构造器。
@Retention指明了注解的生命周期,可以有SOURCE(仅保存在源码中,会被编译器丢弃),CLASS(在class文件中可用,会被VM丢弃)以及RUNTIME(在运行期也被保留)。
@Constraint是最关键的,它表示这个注解是一个验证注解,并且指定了一个实现验证逻辑的验证器。
message()指明了验证失败后返回的提示消息,为@Constraint要求。
groups()和payload()也为@Constraint要求,可默认为空。
public class StudentAgeValidator implements ConstraintValidator{ private Integer min; private Integer max; @Override public void initialize(AgeBetween ageBetween) { this.min = ageBetween.min(); this.max = ageBetween.max(); } @Override public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) { return age > min && age < max; } }
验证器说明:
此验证器需要实现ConstraintValidator接口,重写两个方法。
接口泛型两个参数分别为注解类名和需要验证的数据的类型,此处验证的age为Integer。
initialize 方法见名知意。
isValid 中为自己的验证逻辑,返回一个布尔值。
@Data @NoArgsConstructor @AllArgsConstructor @TableName("student") public class Student { @TableId(type = IdType.AUTO) private Integer id; private String username; private String password; private String gender; @AgeBetween(min=10,max = 20) private Integer age; }
@PostMapping("/testAnnotation") public String testAnnotation(@Valid @RequestBody Student student) { System.out.println(student); return "Student Created"; }
也可以手动来处理错误,加上一个BindingResult来接收验证结果即可。
@PostMapping("/testAnnotation2") public String testAnnotation2(@Valid @RequestBody Student student, BindingResult validateResult) { if (validateResult.hasErrors()) { return validateResult.getAllErrors().get(0).getDefaultMessage(); } return "Student Created"; }
结果:参数错误,返回自定义的验证失败结果。(这里我是返回的注解中定义的message值)
结果:参数正常,返回正常逻辑结果。
结果:参数错误,返回默认的验证失败结果。
@NotNull //不能为空
@Max @Min //最大值,最小值
@Size //长度
@Pattern //正则表达式
@AssertTrue @AssertFalse //断言真假
@Future @Past //时间在当前时间之前或者之后,假如你设置一个闹钟,如果设置在当前时间之前那么肯定是没有任何意义的。
使用例子:
class User{
@NotNull(message = "字段值不能为空")
private String name;
@Max(value = 20,message = "最大长度为20")
private String address;
@Size(max=10,min=5,message = "字段长度要在5-10之间")
private String NickName;
@Pattern(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$",message = "不满足邮箱正则表达式")
private String email;
@AssertTrue(message = "字段为true才能通过")
private boolean isSave;
@Future(message = "时间在当前时间之后才可以通过")
private Date date;
}