注解分为两类,内置的注解和自定义注解。
1、内置
1.1 数据类型
1.1.1 布尔
- @AssertFalse:
- @AssertTrue:
1.1.2 数字
- @DecimalMax(value=, inclusive=):
- @DecimalMin(value=, inclusive=):
- @Digits(integer=, fraction=):
- @Size(min=, max=)
- @Range(min=, max=)
- @Max(value=),@Min(value=),
- @Negative, @NegativeOrZero,
- @Positive, @PositiveOrZero
1.1.3 日期
- @Future:
- @FutureOrPresent:
- @Past:
- @PastOrPresent:
- @DurationMin(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=):
- @DurationMax(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=):
1.1.4 字符串
- @Length(min=, max=)
- @NotBlank:
- @NotNull,@Null
1.1.5 容器
- @NotEmpty
1.2 正则表达式
邮件:@Email,
表达式:@Pattern(regex=, flags=),
url地址:@URL(protocol=, host=, port=, regexp=, flags=)
货币:@Currency(value=)
其他略。
2、自定义
2.1 步骤
自定义校验注解的步骤分为以下四步:
第一步,编写自定义校验规则注解。
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE }) @Retention(RUNTIME) @Documented @Constraint(validatedBy = CheckCaseValidator.class) public @interface CheckCase { // 默认的错误信息 String message() default "{checkCase.default}"; // 默认的分组 Class<?>[] groups() default {}; // 默认的payLoad Class<? extends Payload>[] payload() default {}; // 注解的值 CaseMode value(); }
注解类上的注解含义如下:
- @Target:适用范围,FILED表示字段,METHOD表示方法,PARAMETER表示参数,ANNOTATION_TYPE表示注解类,TYPE_USE表示集合中的泛型参数。
- @Retention:注解的有效阶段。可选值有源码阶段,编译阶段,运行阶段。
- @Documented: 添加JavaDoc注解
- @Constraint:指定该注解对应的校验器。
注解类的属性含义:
- message:错误信息。
- groups:校验规则所属的组。
- payload:一个标识,用于区分不同的校验逻辑,例如运行环境,开发,测试,生产。严重级别,轻微,普通,严重等等。
- value:注解的值
第二步,编写校验器,实现ConstraintValidator接口
public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> { // 大小写模式 private CaseMode caseMode; @Override public void initialize(CheckCase constraintAnnotation) { this.caseMode = constraintAnnotation.value(); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { return true; } }
泛型参数:
第一个参数,表示注解的类型。第二个参数,表示被校验属性或参数的类型。
方法:
- initialize:用于初始化,获取注解的属性值。参数constraintAnnotation表示校验规则注解。
- isValid:用于实现校验逻辑,context表示上下文,可以从中获取一些信息,例如PayLoad
context.unwrap(HibernateConstraintValidatorContext.class).getConstraintValidatorPayload(String.class);
添加Payload的方式,在获取Validator时,添加,.constraintValidatorPayload( "US" );
第三步(可选),配置错误信息。classpath路径下创建ValidationMessage.properties
checkCase.default="The manufacturer must to be upper case"
第四步,使用,验证。
// 制造商名称 @CheckCase(value = CaseMode.UPPER) private String manufacturer;
2.2 上下文对象
上下文对象ConstraintValidatorContext是isValid方法中的第二个参数。
它的方法如下:
- disableDefaultConstraintViolation:默认情况下错误时,会生成ContraintViolation,使用默认的消息模板,该选项禁用默认的消息模板。
- getDefaultConstraintMessageTemplate:获取默认的消息模板, 通常是校验注解类message属性的默认值。
- getClockProvider:在校验日期时使用。不同服务器之间系统时间可能不同步,这种情况下可以提供自定义实现。
- buildConstraintViolationWithTemplate:自定义被校验的对象和消息模板。例如:
context.buildConstraintViolationWithTemplate("{manu_empty}").addPropertyNode("passengers").addConstraintViolation()
5. unwrap:ConstraintValidatorContext是JSR-303中指定的上下文对象,hibernateValidator的上下文对象是它的子接口。
HibernateConstraintValidatorContext validatorContext = context.unwrap(HibernateConstraintValidatorContext.class);
2.3 复合注解
在自定义规则注解上添加其他校验注解,例如CheckCase添加@NotNull
@NotNull
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = CheckCaseValidator.class)
public @interface CheckCase {
// 默认的错误信息
String message() default "{checkCase.default}";
// 默认的分组
Class<?>[] groups() default {};
// 默认的payLoad
Class<? extends Payload>[] payload() default {};
// 注解的值
CaseMode value();
}