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 {@Resourceprivate 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 {@Beanpublic 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:缺少默认组参数,执行结果:金额不能为空
@Testpublic 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:缺少加款组的参数,执行结果:币种不能为空
@Testpublic 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进行抛出异常告警。