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>
相关基础概念查看我的另外两篇博客,
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
/**
* @author ZhangLiFang
* @date 2022/7/1 10:01 PM
* @Desc
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ValidGroupParam {
Class<?>[] value() default Default.class;
}
/**
* @author ZhangLiFang
* @date 2022/7/1 11:41 PM
* @Desc ValidGroupParam校验的参数组
*/
public interface InboundOrderGroup {
/**
* 加款
*/
interface Inbound extends Default {}
/**
* 调额
*/
interface AdjustInCome extends Default {}
}
/**
* @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;
}
/**
* @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();
}
}
/**
* @author ZhangLiFang
* @date 2022/7/4 5:22 PM
* @Desc
*/
@Component
public class ValidatorTemplateFactory {
@Bean
public ValidatorFactory validatorFactory(){
return Validation.buildDefaultValidatorFactory();
}
}
针对加款组调用接口
@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)
即可实现分组校验。
@ValidGroupParam注解支持可多个组参数校验,同时也支持对方法的多个Object参数的constraints进行校验。即
@ValidGroupParam({InboundOrderGroup.Inbound.class, InboundOrderGroup.Inbound2.class})
public void testAnnotation(InboundMidRequest1 inboundMidRequest1, InboundMidRequest2 inboundMidRequest2){
log.info("okkkk,too");
}
注意:以最先匹配到不符合的参数条件的一条message进行抛出异常告警。