Spring AOP和HttpServletRequest

问题描述 投票:0回答:2

我正在开发一个批注,它将向其他微服务发送一些审核事件。说,我正在创建一个实体,并且我的Rest控制器上有一个方法add

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

我定义了与@Audit注释相关的适当方面。

但是这是一个技巧,审核事件的性质要求我需要从HttpServletRequest本身中提取一些元数据。

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

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

spring spring-boot spring-aop spring-rest
2个回答
1
投票

由于您使用的是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();

0
投票

以下是如何使用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代码达到要求的。

希望这会有所帮助

© www.soinside.com 2019 - 2024. All rights reserved.