介绍
在项目开发当中,数据校验是你必须要考虑和面对的事情,为此要写上一大串的代码进行校验,这样就会导致代码冗余和一些管理的问题。
例如下面的代码:
1 public void push(List<Long> userList, String url, String content) { 2 Preconditions.checkArgument(CollectionUtils.isNotEmpty(userList), "用户列表不能为空"); 3 Preconditions.checkArgument(StringUtils.isNotEmpty(url), "推送url不能为空"); 4 Preconditions.checkArgument(StringUtils.isNotEmpty(content), "推送内容不能为空"); 5 }
validation可以做以下事情
- validation可以抛出统一的参数校验异常,方便定位问题
- 编程简单,只需要注解就能搞定,不需要编写大量的代码
validation提供以下注解:
使用
添加JAR包依赖
1 <dependency> 2 <groupId>javax.validation</groupId> 3 <artifactId>validation-api</artifactId> 4 <version>1.1.0.Final</version> 5 </dependency> 6 <!-- hibernate validator--> 7 <dependency> 8 <groupId>org.hibernate</groupId> 9 <artifactId>hibernate-validator</artifactId> 10 <version>5.2.0.Final</version> 11 </dependency>
一、简单的参数校验
1 public class UserBean { 2 @Range(min = 20, max = 50, message = "age应该在[20,50]之间") 3 private Integer age; 4 5 @NotNull(message = "name不能为空") 6 private String name; 7 8 @Length(max = 100, message = "address不能超过100") 9 private String address; 10 11 @Email(message = "email格式不对") 12 private String email; 13 14 15 public Integer getAge() { 16 return age; 17 } 18 19 public void setAge(Integer age) { 20 this.age = age; 21 } 22 23 public String getName() { 24 return name; 25 } 26 27 public void setName(String name) { 28 this.name = name; 29 } 30 31 public String getAddress() { 32 return address; 33 } 34 35 public void setAddress(String address) { 36 this.address = address; 37 } 38 39 40 public String getEmail() { 41 return email; 42 } 43 44 public void setEmail(String email) { 45 this.email = email; 46 } 47 48 }
创建对象验证器
1 /** 2 * 对象验证器 3 * 4 * Created by Albert on 18/1/25. 5 */ 6 public class BeanValidator { 7 8 /** 9 * 验证某个bean的参数 10 * 11 * @param object 被校验的参数 12 * @throws ValidationException 如果参数校验不成功则抛出此异常 13 */ 14 public static <T> void validate(T object) { 15 //获得验证器 16 Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); 17 //执行验证 18 Set<ConstraintViolation<T>> constraintViolations = validator.validate(object); 19 //如果有验证信息,则取出来包装成异常返回 20 if (CollectionUtils.isEmpty(constraintViolations)) { 21 return; 22 } 23 throw new ValidationException(convertErrorMsg(constraintViolations)); 24 } 25 26 /** 27 * 转换异常信息 28 * @param set 29 * @param <T> 30 * @return 31 */ 32 private static <T> String convertErrorMsg(Set<ConstraintViolation<T>> set) { 33 Map<String, StringBuilder> errorMap = new HashMap<>(); 34 String property; 35 for (ConstraintViolation<T> cv : set) { 36 //这里循环获取错误信息,可以自定义格式 37 property = cv.getPropertyPath().toString(); 38 if (errorMap.get(property) != null) { 39 errorMap.get(property).append("," + cv.getMessage()); 40 } else { 41 StringBuilder sb = new StringBuilder(); 42 sb.append(cv.getMessage()); 43 errorMap.put(property, sb); 44 } 45 } 46 return errorMap.toString(); 47 } 48 }
编写测试类
1 public class ValidatorTest { 2 3 public static void main(String[] args) { 4 UserBean userBean = new UserBean(); 5 userBean.setAge(12); 6 userBean.setName("张三"); 7 userBean.setAddress("124444444112"); 8 userBean.setEmail("123"); 9 10 BeanValidator.validate(userBean); 11 } 12 }
运行结果
二、自定义验证器
定义注解,message、groups和payload三个属性是必须定义的。
1 @Target({ElementType.FIELD, ElementType.METHOD}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Constraint(validatedBy = ZipCodeValidator.class) 4 public @interface ZipCode { 5 String message() default ""; 6 Class<?>[] groups() default {}; 7 Class<? extends Payload>[] payload() default {}; 8 }
定义验证类
1 public class ZipCodeValidator implements ConstraintValidator<ZipCode, String> { 2 3 private String zipCodeReg = "[1-9]d{5}(?!d)";//表示邮编的正则表达式 4 private Pattern zipCodePattern = Pattern.compile(zipCodeReg); 5 6 7 @Override 8 public void initialize(ZipCode zipCode) { 9 10 } 11 12 @Override 13 public boolean isValid(String val, ConstraintValidatorContext constraintValidatorContext) { 14 if(val == null) { 15 return true; 16 } 17 return zipCodePattern.matcher(val).matches(); 18 } 19 }
UserBean 加入以下代码
1 @ZipCode(message = "邮编格式错误") 2 private String zipCode; 3 4 public String getZipCode() { 5 return zipCode; 6 } 7 8 public void setZipCode(String zipCode) { 9 this.zipCode = zipCode; 10 }
编写测试类
1 public class ValidatorTest { 2 3 public static void main(String[] args) { 4 UserBean userBean = new UserBean(); 5 userBean.setAge(12); 6 userBean.setName("张三"); 7 userBean.setAddress("124444444112"); 8 userBean.setEmail("123"); 9 10 userBean.setZipCode("000111"); 11 BeanValidator.validate(userBean); 12 } 13 }
运行结果
结语
本文只列举了部分常用的校验方法,还有更多的使用方式,就不在这里一一列举了。