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

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

    • 一、环境
      • 1-1.备注
    • 二、代码实现
      • 2-1.注解定义
      • 2-2.组定义
      • 2-3.constraints使用
      • 2-4.切面定义
      • 2-5.复用ValidatorFactory
      • 2-6.单测校验
      • 2-7.说明

一、环境

springboot+maven

<dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>2.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

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;
}

2-2.组定义

/**
 * @author ZhangLiFang
 * @date 2022/7/1 11:41 PM
 * @Desc ValidGroupParam校验的参数组
 */
public interface InboundOrderGroup {

    /**
     * 加款
     */
    interface Inbound extends Default {}

    /**
     * 调额
     */
    interface AdjustInCome extends Default {}


}

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;
}

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();
    }

}

2-5.复用ValidatorFactory

/**
 * @author ZhangLiFang
 * @date 2022/7/4 5:22 PM
 * @Desc
 */
@Component
public class ValidatorTemplateFactory {

    @Bean
    public ValidatorFactory validatorFactory(){
        return Validation.buildDefaultValidatorFactory();
    }

}

2-6.单测校验

针对加款组调用接口

@Slf4j
@Service
public class AnnotationTestService {

    @ValidGroupParam(InboundOrderGroup.Inbound.class)
    public void testAnnotation(InboundMidRequest inboundMidRequest){
        log.info("okkkk");
    }
}

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

		@Test
    public void test_Annotation_ValidGroupParam_without_default_arg(){
        InboundMidRequest build = InboundMidRequest.builder()
                .amount(null)
                .currency("CNY")
                .platform("平台")
                .build();
        annotationTestService.testAnnotation(build);
    }

单测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);
}

单测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);
    }

单测结果表明,分组成功,@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");
}

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

你可能感兴趣的:(AOP,java,validation,AOP)