你有没有使用过这些编程骚操作(二)- 验证框架(Part C)

简介: 你有没有使用过这些编程骚操作(二)- 验证框架(Part C)

一、高级约束注解

  • 校验参数
  • 校验返回值
  • 校验构造方法

新建service包,新增UserService类,含有一个User属性、有参数和无参数构造方法以及另外两个成员方法

public class UserService {
    private User user;
    // 无参构造函数
    public UserService(){}
    // 包含User的有参构造函数
    public UserService(User user){
    }
}
复制代码

新增一个UserServiceTest

public class UserServiceTest {
    private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    private Set<ConstraintViolation<UserService>> set;
    // 打印结果
    @After
    public void after(){
        set.forEach(item -> {
            // 输出错误信息
            System.out.println(item.getMessage());
        });
    }
}
复制代码

校验方法入参

在UserService类中新增一个insertUser方法,含有User参数,对User参数进行校验,需要使用@Valid注解

public void insertUser(@Valid User user){
    System.out.println("insertUser方法被调用");
}
复制代码

在UserServiceTest类中新增对insertUser方法入参校验的测试方法

@Test
public void testParamValidation() throws NoSuchMethodException {
    ExecutableValidator executableValidator = validator.forExecutables();
    UserService userService = new UserService();
    // 获取待验证的方法
    Method method = userService.getClass().getMethod("insertUser", User.class);
    // 构造方法的入参
    Object[] paramObjects = new Object[]{new User()};
    // 对参数进行校验, 支持填写校验分组,不填默认是Default分组
    set = executableValidator.validateParameters(userService, method, paramObjects);
}
复制代码

利用反射获取目标类中的method,通过构造User,来测试是否能够实现对入惨的校验

执行测试方法

0ff2372294154508ad4fc91c7b9e0e69_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

给user的username属性和password属性赋值,再次执行测试

image.png

校验成功

校验方法返回值

在UserService类中新增一个方法getUserById,该方法返回一个User对象,对返回的User对象进行校验,同样也需要使用到@Valid注解

public @Valid User getUserById(Integer id){
    System.out.println("getUserById方法被调用,userId为:" + id);
    return new User();
}
复制代码

在UserServiceTest中新增测试方法,对getUserById方法的返回值进行校验

@Test
public void testReturnValueValidation() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    ExecutableValidator executableValidator = validator.forExecutables();
    UserService userService = new UserService();
    // 获取待验证的方法
    Method method = userService.getClass().getMethod("getUserById", Integer.class);
    // 调用方法获取返回值
    Object returnVal = method.invoke(userService,1);
    set = executableValidator.validateReturnValue(userService,method,returnVal);
}
复制代码

利用反射获取method,并通过invoke调用目标方法获取返回值,从而对返回值进行校验

执行测试方法

image.png

目标方法被调用,同时抛出校验失败的信息,修改getUserById方法的返回值,给返回的User对象的password和username属性赋值,再次执行测试

image.png

校验成功,无错误提示输出

对构造函数入参进行校验

对构造函数的入参进行校验与对普通函数的入参校验的方式一致,都需要用到@Valid注解。在UserService类的有参构造方法的参数前加上@Valid注解

在UserServiceTest测试类中新增测试方法对构造函数的入参进行校验

@Test
public void testConstructorParamValidation() throws NoSuchMethodException {
    ExecutableValidator executableValidator = validator.forExecutables();
    UserService userService = new UserService();
    // 获取待验证的方法
    Constructor constructor = userService.getClass().getConstructor(User.class);
    // 调用方法获取返回值
    Object[] paramValue = new Object[]{new User()};
    set = executableValidator.validateConstructorParameters(constructor,paramValue);
}
复制代码

注意这里需要调用executableValidator的validateConstructorParameters方对构造函数的入参进行校验,执行该测试方法

image.png

不管是validateParameters方法还是validateReturnValue方法以及validateConstructorParameters方法都有一个groups属性,这个groups与上一篇你有没有使用过这些编程骚操作(三)- 验证框架(中)定义的groups是一样的,即可以将gourps方法入参中,定义分组校验或者定义校验的顺序。

可以使用Spring AOP对每个方法的切面进行校验,构造出入参出参切面,避免一个一个的进行校验 Spring MVC的Controller层的校验就是使用了这种方式。

完整验证步骤

  1. 约束注解的定义
  2. 约束验证规则
  3. 约束注解的声明
  4. 约束验证流程

自定义手机号约束注解

  1. 定义@interface Phone注解
  2. 实现约束验证器PhoneValidator
  3. 声明@Phone约束注解验证
  4. 执行手机号约束验证流程

image.png

验证规则

image.png

使用Optional处理value,如果value为空则赋值空字符串“”

使用自定义的@Phone注解

image.png

测试该注解

image.png


相关文章
|
6月前
|
SQL 分布式计算 Java
Spark学习---SparkSQL(概述、编程、数据的加载和保存、自定义UDFA、项目实战)
Spark学习---SparkSQL(概述、编程、数据的加载和保存、自定义UDFA、项目实战)
379 1
|
SQL 存储 JSON
Spark学习---5、SparkSQL(概述、编程、数据的加载和保存)(二)
Spark学习---5、SparkSQL(概述、编程、数据的加载和保存)(二)
|
SQL 缓存 分布式计算
Spark学习---5、SparkSQL(概述、编程、数据的加载和保存)(一)
Spark学习---5、SparkSQL(概述、编程、数据的加载和保存)(一)
|
JSON jenkins 持续交付
python接口自动化(十六)--参数关联接口后传(详解)
大家对前边的自动化新建任务之后,接着对这个新建任务操作了解之后,希望带小伙伴进一步巩固胜利的果实,夯实基础。因此再在沙场实例演练一下博客园的相关接口。我们用自动化发随笔之后,要想接着对这篇随笔操作,不用说就需 要用参数关联了,发随笔之后会有一个随笔的 id,获取到这个 id,继续操作传这个随笔 id 就可以了(博客园的登录机制已经变了,不能用账号和密码登录了,这里用 cookie 登录)
204 1
python接口自动化(十六)--参数关联接口后传(详解)
|
jenkins 持续交付 Python
python接口自动化(十四)--session关联接口(详解)
上一篇cookie绕过验证码模拟登录博客园,但这只是第一步,一般登录后,还会有其它的操作,如发帖,评论等等,这时候如何保持会话呢?这里我以jenkins平台为例,给小伙伴们在沙场演练一下。
223 0
python接口自动化(十四)--session关联接口(详解)
|
前端开发 Java 数据库连接
你有没有使用过这些编程骚操作(二)- 验证框架(Part A)
你有没有使用过这些编程骚操作(二)- 验证框架(Part A)
你有没有使用过这些编程骚操作(二)- 验证框架(Part A)
你有没有使用过这些编程骚操作(二)- 验证框架(Part B)
你有没有使用过这些编程骚操作(二)- 验证框架(Part B)
你有没有使用过这些编程骚操作(二)- 验证框架(Part B)
|
IDE 开发工具
你有没有使用过这些编程骚操作(一)- Lombok(Part A)(下)
你有没有使用过这些编程骚操作(一)- Lombok(Part A)
你有没有使用过这些编程骚操作(一)- Lombok(Part A)(下)
|
Java 编译器 Go
你有没有使用过这些编程骚操作(一)- Lombok(Part A)(上)
你有没有使用过这些编程骚操作(一)- Lombok(Part A)
你有没有使用过这些编程骚操作(一)- Lombok(Part A)(上)
你有没有使用过这些编程骚操作(一)- Lombok(Part B)(下)
你有没有使用过这些编程骚操作(一)- Lombok(Part B)
你有没有使用过这些编程骚操作(一)- Lombok(Part B)(下)