问题描述
在我的项目中,我想为控制器方法以外的其他方法添加参数验证,我要实现的是在将有效注释添加到方法参数之后,将在方法之前验证由有效注释修改的参数正文被执行。
所以我想到了使用spring的aop进行方法拦截和使用hibernate的validator进行参数验证的想法。一旦实现了这部分功能,我想将其提取到一个可以使用的想法模块中项目中的其他模块。但是,在我将其分离之后,我在其他模块中对其进行了测试,发现我根本无法拦截它。
存在类似的问题,但尚未解决。 Using AspectJ project as a jar in other projects
这里是代码,代码分为两个部分:通用模块和业务模块。通用模块是实现方法拦截和参数验证的项目,业务模块是需要调用参数验证的项目。模块介绍了通用模块。它们的代码结构如下:
- idea项目(父项目,提供依赖关系和版本控制)
- 通用模块
- 业务模块
通用模块
ValidateAspectConfig:
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("top.rainbowecho")
public class ValidateAspectConfig {
}
有效注释:
@Target({ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Valid {
}
ValidateAspect
@Component
@Aspect
public class ValidateAspect {
@Pointcut("execution(* *(..,@top.rainbowecho.common.validate.Valid(*),..))")
public void paramValidatePointCut() {}
@Pointcut("@annotation(top.rainbowecho.common.validate.Valid)")
public void methodValidatePointCut() {}
@Around("paramValidatePointCut()")
public Object validate(ProceedingJoinPoint jp) throws Throwable {
System.out.println("before");
MethodSignature signature = (MethodSignature) jp.getSignature();
Method method = signature.getMethod();
// get parameters and paramter value
Parameter[] parameters = method.getParameters();
Object[] args = jp.getargs();
for (int i = 0; i < parameters.length; i++) {
Valid annotation = parameters[i].getannotation(Valid.class);
if (annotation != null) {
ValidationUtil.fastFailValidate(args[i]);
}
}
return jp.proceed();
}
}
业务模块
检查方法在AIRobot类中
AiRobot
@Component
@Slf4j
public class AiRobot {
public AiReply<TalkAnswer> talk(@Valid Talk talk) throws IOException {
...
}
}
测试结果
在Aspect的拦截逻辑中,必须输出“ before”,但实际测试则不需要。
question = 你是谁
answer = AiReply(ret=0,msg=ok,data={session=1000,answer=xx})
question = 你是怎么来的
answer = AiReply(ret=0,answer=xxx})