Hibernate Validator 是 Bean Validation 的参考实现 。Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。
1.maven中引入hibernate-validator对应的jar:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.1.Final</version>
</dependency>
2. Bean Validator内置的注解
Annotation |
支持的数据类型 |
作用 |
Hibernate metadata impact |
@AssertFalse |
Boolean, boolean |
判断关联属性是否为布尔值false |
没有 |
@AssertTrue |
Boolean, boolean |
检查带注释的元素是否正确。 | 没有 |
@DecimalMax |
BigDecimal, BigInteger, String, byte, short, int,long |
被注解的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示. |
没有 |
@DecimalMin |
BigDecimal, BigInteger, String, byte, short, int,long |
被注解的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示. |
没有 |
@Digits(integer=, fraction=) |
BigDecimal, BigInteger, String, byte, short, int,long |
校验整数位数和小数位数 |
对应的数据库表字段会被设置精度(precision)和准度(scale). |
@Future |
java.util.Date, java.util.Calendar; |
检查给定的日期是否比现在晚. |
没有 |
@Max |
BigDecimal, BigInteger, byte, short, int, long |
检查该值是否小于或等于约束条件中指定的最大值. |
会给对应的数据库表字段添加一个check的约束条件. |
@Min |
BigDecimal, BigInteger, byte, short, int, |
检查该值是否大于或等于约束条件中规定的最小值. |
会给对应的数据库表字段添加一个check的约束条件. |
@NotNull |
Any type |
Checks that the annotated value is notnull. |
对应的表字段不允许为null. |
@Null |
Any type |
Checks that the annotated value is null. |
没有 |
@Past |
java.util.Date, java.util.Calendar; |
检查注解对象中的值表示的日期比当前早. |
没有 |
@Pattern(regex=, flag=) |
String |
检查该字符串是否能够在match指定的情况下被regex定义的正则表达式匹配. |
没有 |
@Size(min=, max=) |
String, Collection, Map and arrays |
校验对象的size。本文作者认为前提是该对象有size()方法,String除外。 |
对应的数据库表字段的长度会被设置成约束中定义的最大值. |
@Valid |
Any non-primitive type |
递归的对关联对象进行校验, 如果关联对象是个集合或者数组, 那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验. |
没有 |
3. Hibernate Validator拓展的注解
Annotation |
支持的数据类型 |
作用 |
Hibernate metadata impact |
@CreditCardNumber |
String |
校验信用卡号码 |
没有 |
|
String |
校验邮件地址 |
没有 |
@Length(min=, max=) |
String |
功能同@Size,但是只支持String类型 |
对应的数据库表字段的长度会被设置成约束中定义的最大值. |
@NotBlank |
String |
不为null,不为空值,不为全空格。功能强大于@NotEmpty |
没有 |
@NotEmpty |
String,Collection,Map, arrays |
校验是否为null或者为空值。功能强于@NotNull |
没有 |
@Range(min=, max=) |
BigDecimal,BigInteger,String, byte,short, int,long |
判断数值的范围,不仅支持数值类型,还支持字符串、字节等等类型 |
没有 |
@SafeHtml(whitelistType=, additionalTags=) |
CharSequence |
无使用价值 |
没有 |
@ScriptAssert(lang=, script=, alias=) |
Any type |
无使用价值 |
没有 |
@URL(protocol=, host=, port=, regexp=, flags=) |
String |
根据RFC2396检查带注释的字符串是否有效的URL。如果指定了任意可选的参数协议、主机或端口,则相应的URL片段必须与指定的值匹配。可选的参数regexp和标志允许指定附加的正则表达式(包括udin)。正则表达式标志,URL必须与之匹配。................................................. |
没有 |
4. Validator框架拓展注解
Annotation |
支持的数据类型 |
作用 |
@NotEmptyPattern |
String |
在字符串不为空的情况下,验证是否匹配正则表达式 |
@ListStringPattern |
List<String> |
验证集合中的字符串是否满足正则表达式 |
@DateValidator |
String |
验证日期格式是否满足正则表达式,Local为ENGLISH |
@DateFormatCheckPattern |
String |
验证日期格式是否满足正则表达式,Local为自己手动指定 |
5. 对象图级联校验
Validator不仅能够校验单个实例对象,还可以校验完整的对象图。对于实例中的对象成员属性,注解上@Valid,就可以被关联校验。
6. 约束条件组合校验
在某些复杂的场景中, 可能还会有更多的约束条件被定义到同一个元素上面, 这可能会让代码看起来有些复杂, 另外, 如果在另外的类里面还有一个相同的属性, 我们可能还要把这些约束条件再拷贝到这个属性上, 但是这样做又违反了 DRY 原则.这个问题可以通过使用组合约束条件来解决.
@NotNull @NotBlank @Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = {}) @Documented public @interface NotNullAndValidCheck { String message() default "必须不为null且属性格式符合要求"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } |
7.验证失败异常捕获
验证失败将会抛出BindException异常
BindingResult bindingResult = ((BindException) e).getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
Map<String, String> errorMsg = new HashMap<>();
for (FieldError fieldError : fieldErrors) {
errorMsg.put(fieldError.getField(), fieldError.getDefaultMessage());
}
8.自定义注解
验证字符串被格式化成集合,验证集合的长度
@Target用于指定使用范围,该处限定只能在字段上使用
@Retention(RetentionPolicy.RUNTIME)表示注解在运行时可以通过反射获取到
@Constraint(validatedBy = xxx.class)指定该注解校验逻辑
8.1 验证的注解
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = FormatStrValidator.class)
public @interface FormateStr {
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String message() default "";
/**
* 分隔符
* @return
*/
String delimiter() default ",";
int min() default 0;
int max() default Integer.MAX_VALUE;
}
8.2 注解实现类
public class FormatStrValidator implements ConstraintValidator<FormateStr, String> {
private static final Log log = LoggerFactory.make();
private int min;
private int max;
private String delimiter;
@Override
public void initialize(FormateStr constraintAnnotation) {
min = constraintAnnotation.min();
max = constraintAnnotation.max();
delimiter = constraintAnnotation.delimiter();
validateParameters();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtils.isBlank(value)) {
return true;
}
int length = value.split(delimiter).length;
return length >= min && length <= max;
}
private void validateParameters() {
if ( min < 0 ) {
throw log.getMinCannotBeNegativeException();
}
if ( max < 0 ) {
throw log.getMaxCannotBeNegativeException();
}
if ( max < min ) {
throw log.getLengthCannotBeNegativeException();
}
}
}