• AspectJ切面自定义注解实现参数分组校验——代码实现(3)


    一、环境

    springboot+maven

    <dependency>
          <groupId>javax.validation</groupId>
          <artifactId>validation-api</artifactId>
          <version>2.0.1.Final</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.5</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1-1.备注

    相关基础概念查看我的另外两篇博客,

    AspectJ切面自定义注解实现参数分组校验——基础概念(1):
    https://blog.csdn.net/weixin_36894490/article/details/125605142?spm=1001.2014.3001.5501

    AspectJ切面自定义注解实现参数分组校验——基础概念(2):
    https://blog.csdn.net/weixin_36894490/article/details/125610487?spm=1001.2014.3001.5501

    二、代码实现

    2-1.注解定义

    /**
     * @author ZhangLiFang
     * @date 2022/7/1 10:01 PM
     * @Desc
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface ValidGroupParam {
    
        Class<?>[] value() default Default.class;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2-2.组定义

    /**
     * @author ZhangLiFang
     * @date 2022/7/1 11:41 PM
     * @Desc ValidGroupParam校验的参数组
     */
    public interface InboundOrderGroup {
    
        /**
         * 加款
         */
        interface Inbound extends Default {}
    
        /**
         * 调额
         */
        interface AdjustInCome extends Default {}
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2-3.constraints使用

    /**
     * @author ZhangLiFang
     * @date 2022/7/1 5:24 PM
     * @Desc
     */
    
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public class InboundMidRequest implements Serializable {
    
        private static final long serialVersionUID = 8666517965899046452L;
    
        /**
         * 金额 默认组校验
         */
        @NotNull(message = "金额不能为空")
        private BigDecimal amount;
        /**
         * 币种 对于加款组需要做校验
         */
        @NotBlank(groups = InboundOrderGroup.Inbound.class, message="币种不能为空")
        private String currency;
        /**
         * 平台 对于调额组需要做校验
         */
        @NotBlank(groups = InboundOrderGroup.AdjustInCome.class, message="平台不能为空")
        private String platform;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    2-4.切面定义

    /**
     * @author ZhangLiFang
     * @date 2022/7/1 10:13 PM
     * @Desc
     */
    @Aspect
    @Component
    public class ValidGroupParamAspect {
    
        @Resource
        private ValidatorFactory factory;
    
        @Pointcut("@annotation(validGroupParam)")
        public void callAt(ValidGroupParam validGroupParam) {
        }
    
        @Around(value = "callAt(validGroupParam)", argNames = "pjp,validGroupParam")
        public Object around(@Valid ProceedingJoinPoint pjp, ValidGroupParam validGroupParam) throws Throwable {
            Validator validator = factory.getValidator();
            for (Object o : pjp.getArgs()) {
                Set<ConstraintViolation<Object>> violations = validator.validate(o, validGroupParam.value());
                for (ConstraintViolation<Object> violation : violations) {
                    String errorMsg = violation.getMessage();
                    throw new BizException(ErrorCode.PARAM_ERROR, errorMsg);
                }
            }
    
            return pjp.proceed();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2-5.复用ValidatorFactory

    /**
     * @author ZhangLiFang
     * @date 2022/7/4 5:22 PM
     * @Desc
     */
    @Component
    public class ValidatorTemplateFactory {
    
        @Bean
        public ValidatorFactory validatorFactory(){
            return Validation.buildDefaultValidatorFactory();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2-6.单测校验

    针对加款组调用接口

    @Slf4j
    @Service
    public class AnnotationTestService {
    
        @ValidGroupParam(InboundOrderGroup.Inbound.class)
        public void testAnnotation(InboundMidRequest inboundMidRequest){
            log.info("okkkk");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    单测1:缺少默认组参数,执行结果:金额不能为空

    		@Test
        public void test_Annotation_ValidGroupParam_without_default_arg(){
            InboundMidRequest build = InboundMidRequest.builder()
                    .amount(null)
                    .currency("CNY")
                    .platform("平台")
                    .build();
            annotationTestService.testAnnotation(build);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    单测2:缺少调额组的参数,执行结果:okkkk

    @Test
    public void test_Annotation_ValidGroupParam_without_other_group_arg(){
        InboundMidRequest build = InboundMidRequest.builder()
                .amount(new BigDecimal("100"))
                .currency("CNY")
                .platform("")
                .build();
        annotationTestService.testAnnotation(build);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    单测3:缺少加款组的参数,执行结果:币种不能为空

    @Test
        public void test_Annotation_ValidGroupParam_without_own_group_arg(){
            InboundMidRequest build = InboundMidRequest.builder()
                    .amount(new BigDecimal("100"))
                    .currency("")
                    .platform("平台")
                    .build();
            annotationTestService.testAnnotation(build);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    单测结果表明,分组成功,@ValidGroupParam(InboundOrderGroup.Inbound.class)即可实现分组校验。

    2-7.说明

    @ValidGroupParam注解支持可多个组参数校验,同时也支持对方法的多个Object参数的constraints进行校验。即

    @ValidGroupParam({InboundOrderGroup.Inbound.class, InboundOrderGroup.Inbound2.class})
    public void testAnnotation(InboundMidRequest1 inboundMidRequest1, InboundMidRequest2 inboundMidRequest2){
    	log.info("okkkk,too");
    }
    
    • 1
    • 2
    • 3
    • 4

    注意:以最先匹配到不符合的参数条件的一条message进行抛出异常告警。

  • 相关阅读:
    基于leetcode的算法训练:Day4
    Python面试高频问题:修改list中某个元素时的坑
    HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)
    轮转数组(超详细!)
    Linux中in、ls、tree、clear的用法
    Python字符串类型详解(三)——字符串类型的格式化
    Django初窥门径-自定义用户模型
    安装 tensorflow GPU(使用 conda)
    定制自己的 AI 角色CustomChar;AI知识点和面试题;提高llama 3 的微调速度Unsloth
    2022年最新Python大数据之Python基础【六】函数与变量
  • 原文地址:https://blog.csdn.net/weixin_36894490/article/details/125610904