Java參數校驗工具validation實踐
阿新 • • 發佈:2018-02-09
jar包依賴 pos jar包 compile mpi 創建 pri nal void
介紹
在項目開發當中,數據校驗是你必須要考慮和面對的事情,為此要寫上一大串的代碼進行校驗,這樣就會導致代碼冗余和一些管理的問題。
例如下面的代碼:
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 }
運行結果
結語
本文只列舉了部分常用的校驗方法,還有更多的使用方式,就不在這裏一一列舉了。
Java參數校驗工具validation實踐