java 正则表达式_a-z_0-9 validation,掌握Java-Bean Validation

数据校验虽然简单,但是却是一个繁琐的事。我在无数的代码看到if判断参数,然后错了打日志抛异常,一片一片的这种代码,如果有点重复了,再弄出N个xxUtil来归纳代码。虽然这种做法可以达到效果,但是代码散乱,一个是编写麻烦,一个是不易阅读。

Java业界最喜欢搞规范,所以参数校验作为一个痛点,JSR 303 – Bean Validation规范出现了。

JSR 303 – Bean Validation

是一个数据验证的规范,2009年11月确定最终方案。2009年12月Java EE 6发布,Bean Validation作为一个重要特性被包含其中。Hibernate Validator是 Bean Validation 的参考实现。Hibernate Validator提供了JSR 303规范中所有内置constraint的实现,除此之外还有一些附加的constraint。

constraint就是约束条件,比如不能为空之类的,这些条件被定义,然后就能被复用,而不是每次都在if语句里写。Bean Validation为Bean的验证定义了元数据模型和API,这里的元数据就是constant,元数据默认的形式是注解,还可以使用xml来定义constraint。

引入Bean Validation

javax.validation

validation-api

1.1.0.Final

org.hibernate

hibernate-validator

5.0.2.Final

javax.el

javax.el-api

3.0.0

org.glassfish.web

javax.el

2.2.6

例子

我们先看看Bean Validation怎么用,有个大体的认识。首先声明需要被校验的Java Bean:

public class User{

@NotNull(message = "用户名不能为空")

private String name;

@Min(value = 1, message = "年龄不能小于1")

@Max(value = 200, message = "年龄不能大于200")

private int age;

// 构造函数,getter,setter略

}

在User Bean中我们使用了几个注解来修饰字段,name字段上添加 @NotNull

表示这个字段不能为空,age字段上添加 @Min

和 @Max

注解,表示限制其最大和最小值。这些constraint注解是Bean Validation规范内置的。全部内置的constraint说明见下文。

然后编写入口函数,实例化Bean并进行校验:

public static void main(String[] args){

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

Set validate = validator.validate(new User(null, 0));

for (ConstraintViolation violation : validate) {

System.out.println(violation.getMessage());

}

}

输出:

用户名不能为空

年龄不能小于1

Bean Validation内置constraint

JSR 303内置了常用的constraint,我们可以直接使用。

空检查

@Null

被注释的元素必须为 null (任何类型)

@NotNull

被注释的元素必须不为 null (任何类型)

布尔检查

@AssertTrue

被注释的元素必须为 true (boolean或者Boolean)

@AssertFalse

被注释的元素必须为 false (boolean或者Boolean)

数字检查

@Min(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值 (BigDecimal,BigInteger,byte,short,int,long及其包装类)

@Max(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值 (CharSequence,BigDecimal,BigInteger,byte,short,int,long及其包装类)

@DecimalMax(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Digits (integer, fraction)

被注释的元素必须是一个数字,其值必须在可接受的范围内 (BigDecimal,BigInteger,byte,short,int,long及其包装类)

字符串(集合)检查

@Size(max, min)

被注释的元素的大小必须在指定的范围内 (CharSequence,Collection,Map,Array)

@Pattern(value)

被注释的元素必须符合指定的正则表达式 (CharSequence)

时间检查

@Past

被注释的元素必须是一个过去的日期 (Date,Calendar)

@Future

被注释的元素必须是一个将来的日期 (Date,Calendar)

Hibernate Validator扩展的constraint

Hibernate除了实现标准的constraint,还实现了一些扩展constraint。

@NotEmpty

被注释的字符串的必须非空

@NotBlank

被注释的字符串的必须非空白

@Range

被注释的元素必须在合适的范围内 (内部使用 @Min

和 @Max

实现)

@Length

被注释的字符串的大小必须在指定的范围内(同 @Size

)

@URL

被注释的字符串必须是合法的URL

@Email

被注释的元素必须是电子邮箱地址

@SafeHtml

被注解的字符串必须是合法的HTML

@CreditCardNumber

被注释的元素必须是合法的信用卡号,使用的是Luhn算法

@ScriptAssert

直接指定脚本进行校验,算是最灵活的了

自定义Constraint

虽然Bean Validation规范提供了内置的constraint,但是对于实际使用来说是根本不够用的,业务的规则千奇百怪,是需要自己自定义constraint的。

定制一个constraint需要两个部分,一个是constraint注解,一个是执行校验逻辑的类。

比如我们想要定制一个UUID格式字符串的constraint,可以这么写:

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Constraint(validatedBy = UUIDValidator.class)

public @interface UUID {

Stringmessage()default "UUID不合法";

Class[] groups() default {};

Class[] payload() default {};

}

constraint注解需要使用 @Constraint(validatedBy = UUIDValidator.class)

来指定这个注解是一个Bean Validation注解,并且指定对应的校验规则实现类。

同时,constraint注解必须是 @Retention(RetentionPolicy.RUNTIME)

,因为在运行是需要使用到注解。

然后编写校验规则实现类:

public class UUIDValidatorimplements ConstraintValidator{

public static final Pattern UUID_PATTERN = Pattern.compile("[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}");

@Override

public void initialize(UUID uuid){

}

@Override

public boolean isValid(String object, ConstraintValidatorContext constraintValidatorContext){

if (object == null){

return true;

}

return UUID_PATTERN.matcher(object).matches();

}

}

实现类需要实现 ConstraintValidator

接口,泛型参数 A

指定该类作用于什么constraint注解上, T

指定这个校验规则作用于什么数据类型。

因为一个constraint注解是可以作用于多种数据类型上的,比如 @Size

即可用于String上,也可以用于集合上,如何做到的呢?就是为一个constraint注解实现多个校验规则实现类,并指定不同的 T

参数。

Bean Validation 2.0

上面说的都是Bean Validation 1.0和1.1。这两个分别是在JavaEE6和JavaEE7中的。对应的JSR是JSR 303。

Bean Validation 2.0是JavaEE8的一部分,只支持Java8+。对应的JSR是JSR 380。

Bean Validation的新功能:

支持验证泛型参数,比如 List positiveNumbers

可以更灵活的验证集合中的Bean,比如 Map customersByType

支持 java.util.Optional

支持JavaFX声明的属性

@Past

和 @Futur

支持JSR 310的时间类型

新增内置constraint:@Email, @NotEmpty, @NotBlank, @Positive, @PositiveOrZero, @Negative, @NegativeOrZero, @PastOrPresent and @FutureOrPresent

所有的内置constraint都是repeatable的

ConstraintValidator#initialize()

是default方法,可选实现

引入Bean Validation 2.0:

javax.validation

validation-api

2.0.0.Final

org.hibernate.validator

hibernate-validator

6.0.2.Final

org.hibernate.validator

hibernate-validator-annotation-processor

6.0.2.Final

javax.el

javax.el-api

3.0.0

org.glassfish.web

javax.el

2.2.6

注意:本文来自木杉的博客。本站无法对本文内容的真实性、完整性、及时性、原创性提供任何保证,请您自行验证核实并承担相关的风险与后果!

CoLaBug.com遵循[CC BY-SA 4.0]分享并保持客观立场,本站不承担此类作品侵权行为的直接责任及连带责任。您有版权、意见、投诉等问题,请通过[eMail]联系我们处理,如需商业授权请联系原作者/原网站。

你可能感兴趣的:(java,正则表达式_a-z_0-9,validation)