在 SpringBoot 应用程序的 ControllerAdvice 中访问 HttpSession

Posted

技术标签:

【中文标题】在 SpringBoot 应用程序的 ControllerAdvice 中访问 HttpSession【英文标题】:Accessing HttpSession in a ControllerAdvice in a SpringBoot application 【发布时间】:2016-07-30 22:33:29 【问题描述】:

我想在 SpringBoot 应用程序的会话中设置一些默认值。理想情况下,我正在考虑使用带有 @ControllerAdvice 注释的类来设置默认值。这很有用,尤其是因为必须对所有页面执行代码 sn-p。

有没有办法在用@ControllerAdvice注解的类中访问HttpSession

【问题讨论】:

为什么不使用拦截器呢? @JSONStatham 这是个好主意! 【参考方案1】:

您可以使用以下方法从您的@ControllerAdvice 中获取会话:

选项1:

 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

HttpSession session = requeset.getSession(true);//true will create if necessary

选项 2:

@Autowired(required=true)
private HttpServletRequest request;

选项 3:

@Context
private HttpServletRequest request;

这是我如何设计一个控制器方面的示例,它拦截所有控制器端点方法:

@Component
@Aspect
class ControllerAdvice

     @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
     void hasRequestMappingAnnotation() 

     @Pointcut("execution(* your.base.package..*Controller.*(..))")
     void isMethodExecution() 

   /**
    * Advice to be executed if this is a method being executed in a Controller class  within our package structure
    * that has the @RequestMapping annotation.
    * @param joinPoint
    * @throws Throwable
    */
    @Before("hasRequestMappingAnnotation() && isMethodExecution()")
    void beforeRequestMappedMethodExecution(JoinPoint joinPoint) 
        String method = joinPoint.getSignature().toShortString();
        System.out.println("Intercepted: " + method);

        //Now do whatever you need to
    

【讨论】:

那真是太好了。无论如何,getRequest() 不存在。此外,我从this 的回答中看到应该使用currentRequestAttributes() 而不是getRequestAttributes() 另外,controlleradvice中的方法应该如何注解,才能在每个controller被调用的时候调用呢? getRequestAttributes 和 getCurrentRequestAttrributes 执行相同的功能,但 getCurrentRequestAttributes: 公开先前绑定的 RequestAttributes 实例(如果有)除外。回退到当前的 JSF FacesContext,如果有的话。 嗯..我使用 groovy,所以它针对我的用例做了一些修改。我已将其更新为 Java 格式。 您能否进一步解释一下您在控制器建议问题中的注释?这与会话无关,对吗?您是在问如何创建建议以拦截每个控制器端点方法?【参考方案2】:

我建议您使用 Spring Interceptors 而不是 @ControllerAdvice。 稍后您可以使用拦截器映射轻松自定义行为。

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-handlermapping-interceptor

@ControllerAdvice 在您想要全局处理一些异常时真的很出色。

【讨论】:

你能不能也展示一下拦截器类应该如何拦截会话? 您究竟使用什么进行会话管理?与 Redis 的春季会议? 是的,我有一个嵌入式 REDIS 实例。但我不认为这会改变什么,对吧?

以上是关于在 SpringBoot 应用程序的 ControllerAdvice 中访问 HttpSession的主要内容,如果未能解决你的问题,请参考以下文章

springboot 登录+增删改查+获取登录人的ip地址

cache-contro页面缓存处理设置

Linux开机报错 or type Contro-D to continue

Install the IIS 6.0 Management Compatibility Components in Windows 7 or in Windows Vista from Contro

Android实例-调用系统APP(XE10+小米2)

javascript中Date对象的应用