Hibernate Validator简单使用
来源:互联网 发布:移动网络转换器 编辑:程序博客网 时间:2024/06/03 03:53
使用的主要的作用:进行注解式的参数校验——让代码更少、更加专注于业务逻辑
参数验证是一个常见的问题,例如验证用户输入的密码是否为空、邮箱是否合法等。但是无论是前端还是后台,都需对用户输入进行验证,以此来保证系统数据的正确性。对于web来说,有些人可能理所当然的想在前端验证就行了,但这样是非常错误的做法,前台的验证一般是通过JavaScript,js代码是可以被禁用和篡改的,所以相对后台检验而言,安全性会低一些。前端代码对于用户来说是透明的,稍微有点技术的人就可以绕过这个验证,直接提交数据到后台。无论是前端网页提交的接口,还是提供给外部的接口,参数验证随处可见,也是必不可少的。总之,一切用户的输入都是不可信的。
基于这样的常识,在后端的代码开发中,参数校验是一个永远也绕不开的话题。然而编写参数校验代码的过程是一个技术含量不高,及其耗时,繁琐的过程。比如极大多数的参数校验代码就是:判断一下用户名是否已经存在、用户名长度是否满足要求、用户填写的邮箱是否合法。年龄参数是不是一个整数等等。为了减少重复代码的开发,许多有技术积淀的公司,一般都会提供一套或多套特有的参数校验工具类。以此减少代码量。这种做法在项目中非常普遍,有了这些工具类库,程序员在编写业务代码的过程中,工作效率可以大大提升。
然而,即便聪明如上述做法,我们的业务逻辑中依然还是可以见到大量的参数校验逻辑,倘若项目架构的不够合理,这些与参数校验逻辑有关的代码量会更多,真是XXX的裹脚布,又臭又长。大量繁杂的参数校验代码混杂在业务逻辑中,一来降低了代码的可读性;二是让人对业务本身的理解难度加大,很多刚加入公司的人往往是通过读码来理解业务的,公司的一些业务培训一般只能讲个大概,然而在阅读代码的过程中稍有不慎便会被这些“额外”的代码扰乱思路,对于新手,那更是异常噩梦,倘若老员工辞职了,撒手抛给新来的,这样的项目能不能维护下去都是个问题了。
以上参考:http://blog.csdn.net/nmgrd/article/details/57088192
Hibernate Validator
Express validation rules in a standardized way using annotation-based constraints and benefit from transparent integration with a wide variety of frameworks.(标准化方式使用基于注释的约束来表达验证规则,并从与各种框架的透明集成中受益),可以扩展,可自定义约束的类型。Hibernate Validator 5.x is the reference implementation Bean Validation 1.1!。hibernate Validator是 Bean Validation 的参考实现,Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint(约束)。为了满足特定的需求,用户还可以自实现更多的constraint以便满足特定的需求。
网址:http://hibernate.org/validator/
参考文档:http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-gettingstarted-createproject
实际的场景
在后台的业务逻辑中,对数据值的校验在各层都存在(展示层,业务层,数据访问层等),并且各层校验的规则又不尽相同,在各层中重复的校验逻辑既导致了不必要的资源消耗,还使得逻辑不够单一(每层都夹杂着校验的逻辑),JSR 303 Bean Validation就是在这种背景下产生的一个数据验证的J2EE规范。使用起来非常的简单规范,而且校验的规则的代码都是一样的,都是基于JavaBean的注解的校验。
实际的使用
** 引入需要的maven配置
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.0.Final</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>el-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.6</version> </dependency>
* 创建需要校验的类*
package com.common.utils.Hibernatevalidatedemo;import org.hibernate.validator.constraints.Email;import javax.validation.constraints.*;import java.util.Date;/** * descrption: 测试类,看看Validate * authohr: wangji * date: 2017-08-12 10:36 */public class ValidateInfoBean { @NotNull(message = "姓名不能为空!") @Min(value = 1, message = "Id只能大于等于1,小于等于10") @Max(value = 10, message = "Id只能大于等于1,小于等于10") private Integer id; @NotNull(message = "姓名不能为空!") @Size(min = 2, max = 4, message = "姓名长度必须在{min}和{max}之间") @Pattern(regexp = "[\u4e00-\u9fa5]+", message = "名称只能输入是中文字符") private String userName; @NotNull(message = "密码不能为空!") @Size(min = 6, max = 12, message = "密码长度必须在{min}和{max}之间") private String passWord; @NotNull(message = "日期不能为空!") @Past(message = "你只能输入过去的日期") private Date birthday; @NotNull(message = "邮件不能为空!") @Email(message = "邮件格式不正确") private String email; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }}
其中该类中用到Max,Min,NotNull,Size等都是JSR 303中内置的约束条件(constraint),还有一些是Hibernate扩充的约束,我们自己也是可以扩充这个约束进行使用。下面看看如何验证吧。
开始校验首先获取校验器
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); Validator validator = validatorFactory.getValidator();
创建一个校验类的实例
ValidateInfoBean infoBean = new ValidateInfoBean(); infoBean.setId(-1); infoBean.setUserName("中国wj"); infoBean.setPassWord("12345"); infoBean.setEmail("testt.com"); infoBean.setBirthday(new Date(2015,3,2));
校验一共有几种校验的方式(返回的都是违反约束的字段的集合)
//特定类实例,然后分组(就是一个校验的标识,确定先后顺序,是否校验等) <T> Set<ConstraintViolation<T>> validate(T object, Class< ?>... groups); //特定实例上的某个字段<T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class< ?>... groups); //使用某个类上的某个字段进行校验 <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups);
输出函数:
public static void pringValidateStr(Set<ConstraintViolation<ValidateInfoBean>> set2) { for (ConstraintViolation<ValidateInfoBean> constraintViolation : set2){ log.info("错误:" + constraintViolation.getMessage()); log.info("字段:"+constraintViolation.getPropertyPath().toString()); } }
校验所有的字段
Set<ConstraintViolation<ValidateInfoBean>> set = validator.validate(infoBean); pringValidateStr(set); 2017-08-12 13:54:50,931 INFO [Version.java:30] : HV000001: Hibernate Validator 5.4.0.Final 2017-08-12 13:54:51,251 INFO [ValidateTest.java:52] : 错误:你只能输入过去的日期 2017-08-12 13:54:51,251 INFO [ValidateTest.java:53] : 字段:birthday 2017-08-12 13:54:51,251 INFO [ValidateTest.java:52] : 错误:Id只能大于等于1,小于等于10 2017-08-12 13:54:51,252 INFO [ValidateTest.java:53] : 字段:id 2017-08-12 13:54:51,252 INFO [ValidateTest.java:52] : 错误:名称只能输入是中文字符 2017-08-12 13:54:51,253 INFO [ValidateTest.java:53] : 字段:userName 2017-08-12 13:54:51,253 INFO [ValidateTest.java:52] : 错误:邮件格式不正确 2017-08-12 13:54:51,253 INFO [ValidateTest.java:53] : 字段:email 2017-08-12 13:54:51,253 INFO [ValidateTest.java:52] : 错误:密码长度必须在6和12之间 2017-08-12 13:54:51,253 INFO [ValidateTest.java:53] : 字段:passWord
特定实例上的某个字段
Set<ConstraintViolation<ValidateInfoBean>> set3 =validator.validateProperty(infoBean,"userName"); pringValidateStr(set3); 2017-08-12 13:59:14,262 INFO [Version.java:30] : HV000001: Hibernate Validator 5.4.0.Final 2017-08-12 13:59:14,556 INFO [ValidateTest.java:52] : 错误:名称只能输入是中文字符 2017-08-12 13:59:14,557 INFO [ValidateTest.java:53] : 字段:userName
使用某个类上的某个字段进行校验
Set<ConstraintViolation<ValidateInfoBean>> set2 =validator.validateValue(ValidateInfoBean.class,"userName","中国lihai"); pringValidateStr(set2); 2017-08-12 14:00:32,533 INFO [Version.java:30] : HV000001: Hibernate Validator 5.4.0.Final 2017-08-12 14:00:33,136 INFO [ValidateTest.java:52] : 错误:名称只能输入是中文字符 2017-08-12 14:00:33,136 INFO [ValidateTest.java:53] : 字段:userName 2017-08-12 14:00:33,137 INFO [ValidateTest.java:52] : 错误:姓名长度必须在2和4之间 2017-08-12 14:00:33,137 INFO [ValidateTest.java:53] : 字段:userName
还有很多这样的约束
@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) 被注释的元素必须符合指定的正则表达式 表 2. Hibernate Validator 附加的 constraint @Email 被注释的元素必须是电子邮箱地址 @Length 被注释的字符串的大小必须在指定的范围内 @NotEmpty 被注释的字符串的必须非空 @Range 被注释的元素必须在合适的范围内
还有校验分组,确定校验哪些,校验的顺序,就是一个简单的标识,可以随便创建一个标识的类的信息。这里创建了两个空的接口。除此之外还有很多的使用,比如继承,级联,详情见官网,这里仅仅简单的查看如何使用。
package com.common.utils.Hibernatevalidatedemo;import lombok.extern.slf4j.Slf4j;import javax.validation.*;import javax.validation.constraints.NotNull;import javax.validation.constraints.Past;import javax.validation.constraints.Pattern;import javax.validation.constraints.Size;import java.util.Date;import java.util.Set;/** * descrption: 校验分组 * authohr: wangji * date: 2017-08-12 14:04 */@GroupSequence({First.class,Second.class,ValidateGroup.class})//类界别校验的顺序@Slf4jpublic class ValidateGroup { @NotNull(message = "姓名不能为空!", groups = {First.class}) @Size(min = 2, max = 4, message = "姓名长度必须在{min}和{max}之间",groups = {First.class}) @Pattern(regexp = "[\u4e00-\u9fa5]+", message = "名称只能输入是中文字符",groups = {First.class}) private String userName; @NotNull(message = "密码不能为空!",groups = {Second.class}) @Size(min = 6, max = 12, message = "密码长度必须在{min}和{max}之间",groups = {Second.class}) private String passWord; @NotNull(message = "日期不能为空!") @Past(message = "你只能输入过去的日期") private Date birthday; public static void main(String[] args) { ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); Validator validator = validatorFactory.getValidator(); ValidateGroup testFirst = new ValidateGroup(); testFirst.setUserName("wangji"); //下面这里使用来分类进行校验,通过Group唯一标识进行区别,也可以使用多个进行先后顺序的校验 //还可以进行类界别的校验顺序@GroupSequence,如果没有定义Group那么就会使用,当前类进行标识 // pringValidateStr(validator.validate(testFirst,First.class));// 2017-08-12 14:22:13,899 INFO [ValidateGroup.java:44] : 错误:姓名长度必须在2和4之间// 2017-08-12 14:22:13,900 INFO [ValidateGroup.java:45] : 字段:userName// 2017-08-12 14:22:13,900 INFO [ValidateGroup.java:44] : 错误:名称只能输入是中文字符// 2017-08-12 14:22:13,900 INFO [ValidateGroup.java:45] : 字段:userName// 通过@GroupSequence指定验证顺序:// 先验证First分组,如果有错误立即返回// 而不会验证Second分组,接着如果First分组验证通过了,// 那么才去验证Second分组,最后指定User.class表示那些没有分组的在最后。// 这样我们就可以实现按顺序验证分组了。 pringValidateStr(validator.validate(testFirst));// 输出的只是第一个校验错误,其他的不继续校验了// 2017-08-12 14:27:46,378 INFO [Version.java:30] : HV000001: Hibernate Validator 5.4.0.Final// 2017-08-12 14:27:46,649 INFO [ValidateGroup.java:55] : 错误:姓名长度必须在2和4之间// 2017-08-12 14:27:46,650 INFO [ValidateGroup.java:56] : 字段:userName// 2017-08-12 14:27:46,650 INFO [ValidateGroup.java:55] : 错误:名称只能输入是中文字符// 2017-08-12 14:27:46,650 INFO [ValidateGroup.java:56] : 字段:userName } public static void pringValidateStr(Set<ConstraintViolation<ValidateGroup>> set2) { for (ConstraintViolation<ValidateGroup> constraintViolation : set2){ log.info("错误:" + constraintViolation.getMessage()); log.info("字段:"+constraintViolation.getPropertyPath().toString()); } } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; }}
以上就是简单的使用,还有很多的新特性,可以参考官方上的说明进行简单的查看。
网址: https://github.com/WangJi92/mybatits-study/blob/master/mybatis-study/study-6-spring-Hibernate/src/main/java/com/common/utils/Hibernatevalidatedemo/ValidateInfoBean.java
- Hibernate Validator简单使用
- 简单实现hibernate-validator拓展
- validator框架简单使用
- Hibernate-validator校验框架使用
- Hibernate validator使用和自定义validator及整合Spring MVC
- Hibernate validator使用和自定义validator及整合Spring MVC
- Hibernate Validator
- Hibernate Validator
- Hibernate Validator
- Hibernate Validator
- springMVC Hibernate Validator验证框架的使用
- Spring Validation(使用Hibernate Validator)
- springmvc 使用 hibernate-validator时失效
- Spring Validation(使用Hibernate Validator)
- springmvc使用hibernate-validator校验器
- Bean Validation和Hibernate Validator使用小记
- 使用hibernate-validator校验报错解决
- Hibernate-validator校验框架使用教程
- JDBC第一版连接数据库测试
- (POJ
- windows下使用Microsoft Speech SDK开发包做语音识别
- android NDK 之C调java属性及方法
- mariadb使用
- Hibernate Validator简单使用
- 集合框架(数据结构之栈和队列)
- C语言实验——时间间隔
- [c#]常用工具类收集
- 反射02:通过反射动态操作类
- Spring项目监听器ContextLoaderListener作用以及Spring工具类
- spring事物注意事项
- 【平衡二叉树】leetcode 110. Balanced Binary Tree
- zoj 1108 FatMouse's Speed 基础dp