zoukankan      html  css  js  c++  java
  • Java参数校验工具validation实践

    介绍

      在项目开发当中,数据校验是你必须要考虑和面对的事情,为此要写上一大串的代码进行校验,这样就会导致代码冗余和一些管理的问题。

    例如下面的代码:

    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 }

       运行结果

    结语

    本文只列举了部分常用的校验方法,还有更多的使用方式,就不在这里一一列举了。

  • 相关阅读:
    洛谷P3003 [USACO10DEC]苹果交货Apple Delivery
    洛谷P1576 最小花费
    洛谷P1821 [USACO07FEB]银牛派对Silver Cow Party
    洛谷P1948 [USACO08JAN]电话线Telephone Lines
    洛谷P3371【模板】单源最短路径
    洛谷P2384最短路
    FirstOfAll
    Proxy模式:管理第三方API
    Abstract Server模式,Adapter模式和Bridge模式
    Observer模式
  • 原文地址:https://www.cnblogs.com/albert1024/p/8436270.html
Copyright © 2011-2022 走看看