我正在开发一个批注,它将向其他微服务发送一些审核事件。说,我正在创建一个实体,并且我的Rest控制器上有一个方法add
。
@PostMapping
@Audit
public ResponseEntity<EntityDTO> add(EntityDTO entity){
...
}
我定义了与@Audit
注释相关的适当方面。
但是这是一个技巧,审核事件的性质要求我需要从HttpServletRequest
本身中提取一些元数据。
而且我不想通过添加(或替换我唯一的参数)HttpServletRequest
对象来修改我的签名。
如何将HttpServletRequest
传递到我的方面?有什么优雅的方法吗?
由于您使用的是Spring MVC,因此请考虑使用Spring MVC拦截器,而不要使用“通用”方面。这些由Spring MVC原生支持,并且可以提供对处理程序和HttpServletRequest
对象的访问
使用拦截器和常规配置,请参见this tutorial
有关处理程序的一些信息,请参见This thread
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;
}
}
NB:Op已接受基于拦截器的答案。这个答案是演示Spring AOP代码达到要求的。
希望这会有所帮助