Spring AOP 和 HttpServletRequest

Spring AOP & HttpServletRequest

我正在处理将一些审计事件发送到其他微服务的注释。 比如说,我正在创建一个实体,我的 Rest 控制器上有一个方法 add

@PostMapping
@Audit
public ResponseEntity<EntityDTO> add(EntityDTO entity){
...
}

我定义了一个适当的方面,它与 @Audit 注释相关联。

但这里有一个技巧,审计事件的性质决定我需要从 HttpServletRequest 本身提取一些元数据。

并且我不想通过添加(或替换我唯一的参数)HttpServletRequest 对象来修改我的签名。

如何将 HttpServletRequest 传递到我的方面?有什么优雅的方法吗?

由于您正在使用 spring MVC,请考虑 Spring MVC 拦截器而不是 "generic" 方面。 这些由 Spring MVC 原生支持,可以提供对处理程序和 HttpServletRequest 对象

的访问

有关使用拦截器和一般配置的信息,请参阅 this tutorial

有关处理程序的一些信息,请参阅

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代码实现需求。

希望对您有所帮助