在工作中不可避免的要面对很多参数校验, 比如写新接口时需要对传入VO的必要字段进行校验, String 是否为空, Integer 最小值, 对象是否为null, 等等.
而使用 hibernate的validator工具对参数进行校验, 可以极大的简化流程, 当然不可避免的就是需要在被校验字段上加上注解信息.
1. 相关依赖
<!-- 参数校验工具 --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>5.4.2.Final</version></dependency><dependency><groupId>org.glassfish.web</groupId><artifactId>el-impl</artifactId><version>2.2</version></dependency>
2. ValidationUtil
对加上相关注解字段进行校验, 使用到 ValidationUtil.java和ValidationResult.java两个文件, 也可在工具中直接抛出异常.
ValidationUtil 内容如下:
package com.liuzhihang.tool.validate;import org.apache.commons.collections.CollectionUtils;import javax.validation.ConstraintViolation;import javax.validation.Validation;import javax.validation.Validator;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.util.Set;/*** 对添加 hibernate.validator 注解的字段进行校验** 使用前 需要引入 hibernate-validator 依赖** @author liuzhihang* @date 2017/11/22 11:08*/public class ValidationUtil {private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();/*** 会 验证 所有字段** @param obj* @param <T>* @return 返回所有不符合的信息*/public static <T> ValidationResult validateAllField(T obj) {ValidationResult result = new ValidationResult(true);StringBuilder errorMsg = new StringBuilder();if (obj == null) {result.setHasPass(false);result.setErrorMsg("The class is null!");return result;}Set<ConstraintViolation<T>> violationSet = validator.validate(obj);if (CollectionUtils.isNotEmpty(violationSet)) {for (ConstraintViolation<T> violation : violationSet) {errorMsg.append(violation.getMessage());}result.setHasPass(false);result.setErrorMsg(errorMsg.toString());}return result;}/*** 验证指定字段 是否符合信息** @param obj* @param fieldName* @param <T>* @return*/public static <T> ValidationResult validateOneField(T obj, String fieldName) {ValidationResult result = new ValidationResult(true);if (obj == null) {result.setHasPass(false);result.setErrorMsg("The class is null!");return result;}Set<ConstraintViolation<T>> violationSet = validator.validateProperty(obj, fieldName);if (CollectionUtils.isNotEmpty(violationSet)) {for (ConstraintViolation<T> violation : violationSet) {result.setHasPass(false);result.setErrorMsg(violation.getMessage());}}return result;}/*** 验证 所有字段, 当第一个不符合时 则直接返回信息** @param obj* @param <T>* @return*/public static <T> ValidationResult validateAllFieldForOneBack(T obj) {ValidationResult result = new ValidationResult(true);if (obj == null) {result.setHasPass(false);result.setErrorMsg("The class is null!");return result;}try {PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(obj.getClass()).getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {result = validateOneField(obj, propertyDescriptor.getName());if (result.getHasPass()) {return result;}}} catch (IntrospectionException e) {result.setHasPass(false);result.setErrorMsg("This validate has error : " + e);}return result;}}
ValidationResult 内容如下:
package com.liuzhihang.tool.validate;/*** @Description:* @Author: liuzhihang* @Date: 2018/1/6 17:57*/public class ValidationResult {private Boolean hasPass;private String errorMsg;public ValidationResult(Boolean hasPass) {this.hasPass = hasPass;}public Boolean getHasPass() {return hasPass;}public void setHasPass(Boolean hasPass) {this.hasPass = hasPass;}public String getErrorMsg() {return errorMsg;}public void setErrorMsg(String errorMsg) {this.errorMsg = errorMsg;}@Overridepublic String toString() {return "ValidationResult{" +"hasPass=" + hasPass +", errorMsg='" + errorMsg + '\'' +'}';}}
3. 常用注解
Bean Validation 中内置的 constraint@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(regex=,flag=) 被注释的元素必须符合指定的正则表达式Hibernate Validator 附加的 constraint@NotBlank(message =) 验证字符串非null,且长度必须大于0@Email 被注释的元素必须是电子邮箱地址@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内@NotEmpty 被注释的字符串的必须非空@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
4 测试示例
代码:
package com.liuzhihang.tool.validate;import lombok.Data;import org.hibernate.validator.constraints.NotBlank;import org.hibernate.validator.constraints.NotEmpty;import javax.validation.constraints.Min;import javax.validation.constraints.NotNull;/*** @author liuzhihang* @date 2017/11/22 18:25*/@Datapublic class ValidationVo {@NotBlank(message = "The name must notEmpty!")private String name;@NotNull(message = "The age must notNull!")@Min(value = 1, message = "The age must greater than 0!")private Integer age;public static void main(String[] args) {ValidationVo validationVo = new ValidationVo();System.out.println(ValidationUtil.validateAllField(validationVo).toString());validationVo.setAge(1);System.out.println(ValidationUtil.validateAllField(validationVo).toString());validationVo.setName("二蛋");System.out.println(ValidationUtil.validateAllField(validationVo).toString());}}
输出结果:
ValidationResult{hasPass=false, errorMsg='The name must notEmpty!The age must notNull!'}ValidationResult{hasPass=false, errorMsg='The name must notEmpty!'}ValidationResult{hasPass=true, errorMsg='null'}
