Hibernate Validate提供了很丰富的内置验证注解。当这些还不能满足你的要求,我们可以自定义验证注解。
比如:我们自定义一个关键字过滤的验证规则注解如下。
package com.yyoo.springmvc.valid;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {KeyWordValidator.class})
@documented
@Repeatable(KeyWord.List.class)
public @interface KeyWord {
String message() default "{com.yyoo.springmvc.valid.KeyWord.message}";
Class>[] groups() default { };
Class extends Payload>[] payload() default { };
String keyWords() default "";
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@documented
@interface List {
KeyWord[] value();
}
}
几个元注解的解释
- @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE }):定义约束支持的目标元素类型。@KeyWord可用于字段(元素类型FIELD)、JavaBeans 属性以及方法返回值(METHOD)、方法/构造函数参数(PARAMETER)和参数化类型的类型参数(TYPE_USE)。元素类型ANNOTATION_TYPE允许创建构成约束的基础上@KeyWord。
- @Retention(RetentionPolicy.RUNTIME): 该类型的注解将在运行时通过反射的方式可用(我们定义一般都使用该方式)
@Constraint(validatedBy = {KeyWordValidator.class}): 将注解类型标记为约束注解,并指定对应的验证器类为KeyWordValidator(验证器我们在下文定义)。如果约束可以用于多种数据类型,则可以指定多个验证器,每个数据类型一个。 - @documented: 注解是否将包含在JavaDoc中
- @Repeatable(List.class):表示注解可以在同一个地方重复多次,通常配置不同。List就是我们注解类中的定义的内部注解List。
- message:错误消息属性。我们设置了默认值{com.yyoo.springmvc.valid.KeyWord.message},表示它将读取国际化文件的消息配置
- groups:指定验证组。这必须默认为 Class> 类型的空数组。
- payload:Jakarta Bean Validation API 的客户端可以使用该属性将自定义负载对象分配给约束。API 本身不使用此属性。
示例中keyWords属性是我们的自定义属性,可根据自身的需求进行定义。
内部注释List它允许@CheckCase在同一元素上指定多个 注释,例如使用不同的验证组和消息。虽然可以使用另一个名称,但 Jakarta Bean 验证规范建议使用 List 并使注释成为相应约束类型的内部注释。
2. 定义验证器类KeyWordValidatorpackage com.yyoo.springmvc.valid; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class KeyWordValidator implements ConstraintValidatorjavax.validation.ConstraintValidator接口{ private String keyWords; @Override public void initialize(KeyWord constraintAnnotation) { // 将注解上初始化的值导入 this.keyWords = constraintAnnotation.keyWords(); } @Override public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { // 一个简单的规则,如果包含关键字则不通过 if(this.keyWords.contains(s)){ return false; } return true; } }
每个自定义验证器,都需要实现该接口
ConstraintValidatorContextinitialize方法提供验证器的初始化,如我们的示例,就是将我们在使用注解的时候赋值的keyWords属性,将其值导入到我们的当前验证器。然后在isValid方法中使用。
我们的示例没有使用该参数。但比如我们需要在验证器中定义一些其他的提示信息,我们可以如下使用:
if ( !isValid ) {
constraintContext.disableDefaultConstraintViolation();
constraintContext.buildConstraintViolationWithTemplate(
"{com.yyoo.springmvc.valid.KeyWord.other.message}"
)
.addConstraintViolation();
}
更多的高级用法和功能(如自定义验证注解、自定义交叉验证等)请参考Hibernate Validator
上一篇:006-Spring MVC参数验证2-分组验证
下一篇:008-Spring MVC ViewResolver视图解析器



