• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

从零开始的Spring Session(二)

技术杂谈 勤劳的小蚂蚁 4个月前 (12-30) 100次浏览 已收录 0个评论 扫描二维码

上一篇文章中介绍了一些Session和Cookie的基础知识,这篇文章开始正式介绍Spring Session是如何对传统的Session进行改造的。官网这么介绍Spring Session
Spring Session provides an API and implementations for managing a user’s session information. It also provides transparent integration with:
  • HttpSession – allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way. Additional features include:
    • Clustered Sessions – Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution.
    • Multiple Browser Sessions – Spring Session supports managing multiple users’ sessions in a single browser instance (i.e. multiple authenticated accounts similar to Google).
    • RESTful APIs – Spring Session allows providing session ids in headers to work with RESTful APIs
  • WebSocket – provides the ability to keep the HttpSession alive when receiving WebSocket messages
其具体的特性非常之多,具体的内容可以从文档中了解到,笔者做一点自己的总结,Spring Session的特性包括但不限于以下:
  • 使用GemFire来构建C/S架构的httpSession(不关注)
  • 使用第三方仓储来实现集群session管理,也就是常说的分布式session容器,替换应用容器(如tomcat的session容器)。仓储的实现,Spring Session提供了三个实现(redis,mongodb,jdbc),其中redis使我们最常用的。程序的实现,使用AOP技术,几乎可以做到透明化地替换。(核心)
  • 可以非常方便的扩展Cookie和自定义Session相关的Listener,Filter。
  • 可以很方便的与Spring Security集成,增加诸如findSessionsByUserName,rememberMe,限制同一个账号可以同时在线的Session数(如设置成1,即可达到把前一次登录顶掉的效果)等等
介绍完特性,下面开始一步步集成Spring Session

使用Redis集成Spring Session

  • 引入依赖,Spring Boot的版本采用1.5.4
  1. <dependency>
  2.    <groupId>org.springframework.boot</groupId>
  3.    <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6.    <groupId>org.springframework.session</groupId>
  7.    <artifactId>spring-session-data-redis</artifactId>
  8. </dependency>
  • 配置
配置类开启Redis Http Session
  1. @Configuration
  2. @EnableRedisHttpSession
  3. publicclassHttpSessionConfig{
  4. }
基本是0配置,只需要让主配置扫描到@EnableRedisHttpSession即可
配置文件application.yml,配置连接的redis信息
  1. spring:
  2.  redis:
  3.    host: localhost
  4.    port:6379
  5.    database:0
  • 编写测试Controller,以便于观察Spring Session的特性,和前一篇文章使用同样的代码
  1. @Controller
  2. publicclassCookieController{
  3.    @RequestMapping("/test/cookie")
  4.    publicString cookie(@RequestParam("browser")String browser,HttpServletRequest request,HttpSession session){
  5.        //取出session中的browser
  6.        Object sessionBrowser = session.getAttribute("browser");
  7.        if(sessionBrowser ==null){
  8.            System.out.println("不存在session,设置browser="+ browser);
  9.            session.setAttribute("browser", browser);
  10.        }else{
  11.            System.out.println("存在session,browser="+ sessionBrowser.toString());
  12.        }
  13.        Cookie[] cookies = request.getCookies();
  14.        if(cookies !=null&& cookies.length >0){
  15.            for(Cookie cookie : cookies){
  16.                System.out.println(cookie.getName()+" : "+ cookie.getValue());
  17.            }
  18.        }
  19.        return"index";
  20.    }
  21. }
启动类省略,下面开始测试。
在浏览器中访问如下端点: http://localhost:8080/test/cookie?browser=chrome,下面是连续访问4次的结果
  1. 1    不存在session,设置browser=chrome
  2. 2    存在sessionbrowser=chrome
  3.    SESSION :70791b17-83e1-42db-8894-73fbd2f2a159
  4. 3    存在sessionbrowser=chrome
  5.    SESSION :70791b17-83e1-42db-8894-73fbd2f2a159
  6. 4    存在sessionbrowser=chrome
  7.    SESSION :70791b17-83e1-42db-8894-73fbd2f2a159
如果还记得上一篇文章中运行结果的话,会发现和原生的session管理是有一些差别,原先的信息中我们记得Cookie中记录的Key值是JSESSIONID,而替换成RedisHttpSession之后变成了SESSION。接着观察redis中的变化:
解析一下这个redis store,如果不纠结于细节,可以跳过,不影响使用。
1. spring:session是默认的Redis HttpSession前缀(redis中,我们常用’:’作为分割符)。
2. 每一个session都会有三个相关的key,第三个key最为重要,它是一个HASH数据结构,将内存中的session信息序列化到了redis中。如上文的browser,就被记录为sessionAttr:browser=chrome,还有一些meta信息,如创建时间,最后访问时间等。
3. 另外两个key,expirations:1504446540000和sessions:expires:7079…我发现大多数的文章都没有对其分析,前者是一个SET类型,后者是一个STRING类型,可能会有读者发出这样的疑问,redis自身就有过期时间的设置方式TTL,为什么要额外添加两个key来维持session过期的特性呢?这需要对redis有一定深入的了解才能想到这层设计。当然这不是本节的重点,简单提一下:redis清除过期key的行为是一个异步行为且是一个低优先级的行为,用文档中的原话来说便是,可能会导致session不被清除。于是引入了专门的expiresKey,来专门负责session的清除,包括我们自己在使用redis时也需要关注这一点。在开发层面,我们仅仅需要关注第三个key就行了。

总结

本节主要讲解了Spring Boot如何集成Spring Session,下一节将介绍更加复杂的特性。包括自定义Cookie序列化策略,与Spring Security的集成,根据用户名查找session等特性以及使用注意点。

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:从零开始的Spring Session(二)
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00