关于版本之间的差异其实不是本文说明的重点,毕竟2.0做到了很好的向下兼容,使用起来是无缝的。
但是本处还是给个1.1版本和2.0.1的截图,感官上简单对比一下区别:
兼容性表格 Bean Validation Hibernate Validation JDK Spring Boot
1.1 5.4 + 6+ 1.5.x
2.0 6.0 + 8+ 2.0.x
关于Bean Validation 2.0的关注点(新特性)
因为2.0推出的时间确实不算长,so此处我把一些重要的关注点列举如下:
对Java的最低版本要求是Java 8
支持容器的校验,通过TYPE_USE类型的注解实现对容器内容的约束:List<@Email String>
支持日期/时间的校验,@Past和@Future
拓展元数据(新增注解):@Email,@NotEmpty,@NotBlank,@Positive, @PositiveOrZero,@Negative,@NegativeOrZero,@PastOrPresent和@FutureOrPresent
1. 像@Email、@NotEmpty、@NotBlank之前是Hibernate额外提供的,2.0标准后hibernate自动退位让贤并且标注为过期了
Bean Validation 2.0的唯一实现为Hibernate Validator。(其实还有Apache BVal,但是你懂的,forget it)
对于Hibernate Validator,它自己也扩展了一些注解支持。
1. 6.0以上版本新增(对应标准2.0版本):@UniqueElements、@ISBN、@CodePointLength
2. 6.0以下版本可以使用的: @URL、@ScriptAssert、@SafeHtml、@Range、@ParameterScriptAssert、@Mod11Check、@Mod10Check、@LuhnCheck、@Length、@EAN、@Currency、@CreditCardNumber、@ConstraintComposition、
3. Hibernate Validator默认会校验完所有的属性,然后返回所有的验证失败信息。开启fail fast mode后,只要有一个验证失败,则返回验证失败信息。
so,对于Java Bean Validation的实现落地产品就没啥好选的,导入Hibernate Validator(最新版本)吧:
<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.17.Final</version> </dependency>==小细节:==
可以看到,导入了hibernate-validator就必要再自己导入Java Bean ValidationAPI了,因此建议不用再手动导入API,交给内部来管理依赖。
定义一个待校验的普通JavaBean:
@Getter @Setter @ToString public class Person { // 错误消息message是可以自定义的 @NotNull(message = "名字不能为null") public String name; @Positive public Integer age; @NotNull @NotEmpty private List<@Email String> emails; @Future private Date start; }书写测试用例:
public static void main(String[] args) { Person person = new Person(); //person.setName("fsx"); person.setAge(-1); // email校验:虽然是List都可以校验哦 person.setEmails(Arrays.asList("fsx@gmail.com", "baidu@baidu.com", "aaa.com")); //person.setStart(new Date()); //start 需要是一个将来的时间: Sun Jul 21 10:45:03 CST 2019 //person.setStart(new Date(System.currentTimeMillis() + 10000)); //校验通过 // 对person进行校验然后拿到结果(显然使用时默认的校验器) 会保留下校验失败的消息 Set<ConstraintViolation<Person>> result = Validation.buildDefaultValidatorFactory().getValidator().validate(person); // 对结果进行遍历输出 result.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": " + v.getInvalidValue()) .forEach(System.out::println); }运行,报错啦:
Caused by: java.lang.ClassNotFoundException: javax.el.ELManager at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ...可以看到运行必须依赖于javax.el这个包。(其实我是比较费解的,为何校验框架非得依赖它呢?有小伙伴可以帮忙解释一下吗?)
那行,导入依赖javax.el以及它的实现:
<!-- 注意这里导入的是Apr, 2013发布的el3.x的版本,但是glassfish并没有对此版本进行支持了 当然tomcat肯定是支持的 --> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>3.0.1-b06</version> </dependency> <!-- servlet容器大都对el有实现(支持jsp的都对此有实现),比如tomcat/glassfish等 --> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.6</version> </dependency>