JSR

JSR是Java Specification Requests的缩写,意思是Java 规范提案。

JSR-303

JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。

Bean Validation 中内置的 constraint

Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式

Hibernate Validator 附加的 constraint

Constraint 详细信息
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内

自定义 constraint

有时无论是原配的 constraint 还是 Hibernate Validator 附加的 constraint 都不满足我们的实际生产需求。这时候我们就需要自己定义属于自己的 constraint。

以验证这不是个纯数字的字符串为例。

面对这个需求我们首先会想到使用 Bean Validation 的 @Pattern(value)并结合正则表达式来解决,在 js 中,我们使用该逻辑的正则表达式很简单:!/^\d+$/。但是在 JSR 303 中,对于@Pattern(value),我们无法做非逻辑处理。因此,这时候我们就很有必要定义自己的 constraint 来满足需求。

自定义 constraint 的步骤如下:

  1. 定义验证标签

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import javax.validation.Constraint;
    import javax.validation.Payload;
    @Documented
    @Constraint(validatedBy = { IsNotNumValidator.class })
    @Target({ElementType.METHOD, ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface IsNotNum {
    String message() default "这不是一个纯数字!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    }
  2. 定义标签所依赖的验证逻辑

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import java.util.regex.Pattern;
    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    public class IsNotNumValidator implements ConstraintValidator<IsNotNum, String> {
    @Override
    public void initialize(IsNotNum isNotNum) {
    }
    @Override
    public boolean isValid(String str, ConstraintValidatorContext ctx) {
    Pattern pattern = Pattern.compile("^\\d+$");
    return !pattern.matcher(str).matches();
    }
    }
  3. 在 Java Bean 中使用自定义的 constraint

    1
    2
    @IsNotNum(message="用户名不能是纯数字,请重新输入!")
    private String userName;

    这里可以不使用默认的 message。