背景
项目使用的是hibernate validation校验框架(不懂的可以参考这篇文章:Bean Validation)。对二维码id的校验,需要校验长度及非法字符。由于非法字符是通过正则表达式匹配的,存在效率不高的问题,需要控制下校验顺序,即先校验长度,然后再校验正则表达式。
解决方案
hibernage validtaion框架有校验分组的概念,指定校验注解的时候可以加上分组,如果没有指定,那么默认是Default分组。我们先创建一个分组:
public interface Extended{}
然后校验注解指定属于这个分组:
@Length(min=3,max=100) // @Length没有指定group,则属于Default分组
@CharValid(groups = Extended.class) // @CharValid是个自定义校验注解
String id;
然后创建一个分组顺序:
@GroupSequence({Default.class, Extended.class})
public interface MySequence {}
通过@GroupSequence指定分组顺序,例如这里先校验Default分组,再校验Extended分组。然后将这个顺序作为参数传入校验方法:
validator.validate(object, MySequence.class);
问题:
虽然指定了校验顺序,但是还是会去校验@CharValid注解,还是会导致效率问题。这里需要让@Length校验不通过时就直接返回,因此需要把校验模式改为快速失败:
// 原来的validator获取方式
//ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
//validator = factory.getValidator();
validator = Validation.byProvider( HibernateValidator.class )
.configure()
.failFast( true ) // 设置快速失败
.buildValidatorFactory()
.getValidator();
这样一来@Length校验不通过的话,就不会再去校验后面的东西了,直接返回结果。