在web工程中,对于用户的录入,都是要做校验,有格式的校验,也有逻辑的校验。
举例:
格式的校验:时间格式的校验,数字格式的校验,取值范围的校验
逻辑的校验:结束时间必须大于等于开始时间,结束时间必须大于当前时间
jdk提供了 javax.validation 接口的定义
hibernate-validator 是对其的实现,也是项目中最常用的,例如:Spring mvn 就采用其做为校验框架。
官网为:
http://hibernate.org/validator/
pom.xml 引入
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
<version>2.1.1</version>
</dependency>
对其中简单使用方式 请参考官网。
在此特举例@ScriptAssert的配置:
要求:
1、身份证可以为空,如果不为空必须为14 或 18 位。
2、年龄要么不填写为0,要么在10 到 100 岁之间
3、身高要么不填写为0,要么在10 到 100 之间。
以上三个要求项目,如果使用普通max 和 min 是无法实现的,要么就要自定义校验器,由于jdk各个注解之间的逻辑是并的关系,所以很难支持
解决方案:jdk 默认支持 js的脚本执行。以及 使用apache的 jexl的表达式。
例如:
@ScriptAssert.List(value = {
@ScriptAssert(lang = "jexl" ,script = "_this.cid == '' || (_this.cid.length()==14 || _this.cid.length()==18)",message = "用户身份证号格式错误")
,@ScriptAssert(lang = "jexl" ,script = "_this.age == 0 || (_this.age>=10 && _this.age<=100)",message = "用户年龄错误")
,@ScriptAssert(lang = "jexl" ,script = "_this.height == 0 || (_this.height>=10 && _this.height<=100)",message = "用户身高错误")
})
public class User {
private String cid;
private int age;
private int height;
//set get ...
}
测试:
@org.junit.Test
public void testHibernate() {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
User user = new User();
user.setCid("123456789789456123");
user.setAge(0);
user.setHeight(15);
Set<ConstraintViolation<User>> set = validator.validate(user);
for(ConstraintViolation<User> item :set){
System.out.println(item.getMessage());
}
}
存在的问题:
对于下面的更复杂的需求,hibernate-validator 是很难甚至无法支持。
因为注解之间的 “并” 关系 导致 逻辑判断的无法灵活有效的中止。
/**
* 身份证信息
* @author [email protected]
* @date 2013-12-18下午3:53:06
*
* * 1、createDate 可以为空,endDate 也可以为空,如果不为空,那么他们必须是yyyy-MM-dd的时间格式
* 2、如果endDate不为空,那么endDate的时间必须大于当前时间
* 3、如果createDate不为空,并且endDate不为空,endDate 必须大于createDate的时间
* 4、cardID身份证号,为空,或在长度必须为14 或者 18 个字符
*/
public class User{
private String cid;
private Date createDate;
private Date endDate;
// get set ...
}