我正在处理一个注释,该注释将向其他微服务发送一些审核事件。 假设我正在创建一个实体,并且我的 Rest 控制器上有一个方法add
。
@PostMapping
@Audit
public ResponseEntity<EntityDTO> add(EntityDTO entity){
...
}
我定义了一个适当的方面,与@Audit
注释相关联。
但这里有一个技巧,审计事件的性质决定了我需要从HttpServletRequest
本身中提取一些元数据。
而且我不想通过添加(或替换我唯一的参数(HttpServletRequest
对象来修改我的签名。
我怎样才能HttpServletRequest
传递到我的方面?有什么优雅的方法吗?
由于您使用的是 Spring MVC,请考虑使用 Spring MVC 拦截器而不是"通用"方面。 这些由Spring MVC本机支持,并且可以提供对处理程序和HttpServletRequest
对象的访问
。请参阅本教程,了解如何使用拦截器和常规配置
有关处理程序的一些信息,请参阅此线程
final HandlerMethod handlerMethod = (HandlerMethod) handler; // this is what you'll get in the methods of the interceptor in the form of Object
final Method method = handlerMethod.getMethod();
以下是如何使用 Spring AOP 完成。
示例注释。
@Retention(RUNTIME)
@Target({ TYPE, METHOD })
public @interface Audit {
String detail();
}
以及相应的方面
@Component
@Aspect
public class AuditAspect {
@Around("@annotation(audit) && within(com.package.web.controller..*)")
public Object audit(ProceedingJoinPoint pjp, Audit audit) throws Throwable {
// Get the annotation detail
String detail = audit.detail();
Object obj = null;
//Get the HttpServletRequest currently bound to the thread.
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
try {
// audit code
System.out.println(detail);
System.out.println(request.getContextPath());
obj = pjp.proceed();
} catch (Exception e) {
// Log Exception;
}
// audit code
return obj;
}
}
注意:Op已经接受了基于拦截器的答案。这个答案是演示Spring AOP代码来实现要求。
希望这有帮助