上一篇文章介绍了一些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
alive when receiving WebSocket messages 其具体的特性非常之多,具体的内容可以从文档中了解到,笔者做一点自己的总结,Spring Session的特性包括但不限于以下:
介绍完特性,下面开始一步步集成Spring Session
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
配置类开启Redis Http Session
@Configuration @EnableRedisHttpSession public class HttpSessionConfig{ }
基本是0配置,只需要让主配置扫描到@EnableRedisHttpSession即可
配置文件application.yml,配置连接的redis信息
spring: redis: host: localhost port: 6379 database: 0
@Controller public class CookieController{ @RequestMapping("/test/cookie") publicStringcookie(@RequestParam("browser")String browser, HttpServletRequest request, HttpSession session){ //取出session中的browser Object sessionBrowser = session.getAttribute("browser"); if (sessionBrowser == null) { System.out.println("不存在session,设置browser=" + browser); session.setAttribute("browser", browser); } else { System.out.println("存在session,browser=" + sessionBrowser.toString()); } Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { System.out.println(cookie.getName() + " : " + cookie.getValue()); } } return "index"; } }
启动类省略,下面开始测试。
在浏览器中访问如下端点: http://localhost:8080/test/cookie?browser=chrome
,下面是连续访问4次的结果
1 不存在session,设置browser=chrome 2 存在session,browser=chrome SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159 3 存在session,browser=chrome SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159 4 存在session,browser=chrome 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等特性以及使用注意点。
如果您有任何想法或问题需要讨论或交流,可进入交流区发表您的想法或问题。