Re:从零开始的Spring Session(二)
上一篇文章介绍了一些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
2
3
4
5
6
7
8<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
1
2
3
4
5@Configuration
@EnableRedisHttpSession
public class HttpSessionConfig { }基本是0配置,只需要让主配置扫描到@EnableRedisHttpSession即可
配置文件application.yml,配置连接的redis信息
1
2
3
4
5spring:
redis:
host: localhost
port: 6379
database: 0编写测试Controller,以便于观察Spring Session的特性,和前一篇文章使用同样的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22@Controller
public class CookieController { @RequestMapping("/test/cookie")
public String cookie(@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 |
1 不存在session,设置browser=chrome |
如果还记得上一篇文章中运行结果的话,会发现和原生的session管理是有一些差别,原先的信息中我们记得Cookie中记录的Key值是JSESSIONID,而替换成RedisHttpSession之后变成了SESSION。接着观察redis中的变化:
redis中的session
解析一下这个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等特性以及使用注意点。
https://www.cnkirito.moe/spring-session-2/
Re:从零开始的Spring Session(二)的更多相关文章
- Re:从零开始的Spring Session(三)
上一篇文章中,我们使用Redis集成了Spring Session.大多数的配置都是Spring Boot帮我们自动配置的,这一节我们介绍一点Spring Session较为高级的特性. 集成Spri ...
- Re:从零开始的Spring Session(一)
Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了.最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇 ...
- (转)从零开始的Spring Session(一)
Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了.最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇 ...
- 从零开始的Spring Session(一)
Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了.最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇 ...
- 从零开始学spring cloud(二) -------- 开始使用Spring Cloud实战微服务
1.准备工作 2.服务提供者与服务消费者 3.服务发现与服务注册 服务发现: 服务注册表: 服务注册表是一个记录当前可用服务实例的网络信息的数据库,是服务发现机制的核心.服务注册表提供查询API和管理 ...
- (38)Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】
[本文章是否对你有用以及是否有好的建议,请留言] 在使用spring boot做负载均衡的时候,多个app之间的session要保持一致,这样负载到不同的app时候,在一个app登录之后,而访问到另外 ...
- 17、Spring Boot普通类调用bean【从零开始学Spring Boot】
转载:http://blog.csdn.net/linxingliang/article/details/52013017 我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个 ...
- 63.JPA/Hibernate/Spring Data概念【从零开始学Spring Boot】
[从零开始学习Spirng Boot-常见异常汇总] 事情的起源,无意当中在一个群里看到这么一句描述:"有人么?默默的问一句,现在开发用mybatis还是hibernate还是jpa&quo ...
- 60. Spring Boot写后感【从零开始学Spring Boot】
从2016年4月15日到2016年7月20日经历长达3个月的时间,[从零开始学习Spring Boot]系列就要告一段落了.国内的各种资源都比较乱或者是copy 来copy去的,错了也不加以修正下,导 ...
随机推荐
- Android-Kotlin-when&类型推断
Kotlin的when表达式 TextEngine 描述文字处理对象: package cn.kotlin.kotlin_base02 /** * 描述文字处理对象 * * val textConte ...
- AlexNet详解
在imagenet上的图像分类challenge上Alex提出的alexnet网络结构模型赢得了2012届的冠军.要研究CNN类型DL网络模型在图像分类上的应用,就逃不开研究alexnet,这是CNN ...
- 【转】jQuery.validate 用法
名称 返回类型 描述 validate(options) 返回:Validator ...
- spring注解方式 idea报could not autowire
删除项目的iml文件,然后mvn重新导入 reimport
- C#基础复习(4) 之 浅析List、Dictionary
参考资料 [1] .netCore 源码 https://github.com/dotnet/corefx [2] <Unity 3D脚本编程 使用C#语言开发跨平台游戏>陈嘉栋著 [3] ...
- 记Asp.Net Core Swagger 使用 并带域接口处理
引用作者原话:Asp.Net的WebApi中使用Swagger作为说明和测试的页面是非常不错的,比起WebApiTestClient来至少在界面上的很大的提升.但是使用Swagger时如果只是一般的控 ...
- JVM活学活用——类加载机制
类的实例化过程 有父类的情况 1. 加载父类静态 1.1 为静态属性分配存储空间并赋初始值 1.2 执行静态初始化块和静态初始化语句(从上至下) 2. 加载子类静态 2.1 为静态 ...
- delphi datetimepicker 修改时间无效问题
今天用delphi写个程序,使用datetimepicker获得想要的时间.蛋疼的问题是无论怎么调整明明看着控件里面的日期变了,但是show出来的datetimepicker.datetime日期都不 ...
- 跟着刚哥学习Spring框架--AOP(五)
AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.OOP引入 ...
- Spring Boot log4j实现把日志存入mongodb
准备工作 1.自定义appender的实现 log4j提供的输出器实现自Appender接口,要自定义appender输出到MongoDB,只需要继承AppenderSkeleton类,并实现几个方法 ...