Spring Boot从入门到精通(七)集成Redis实现Session共享
单点登录(SSO)是指在多个应用系统中,登录用户只需要登录验证一次就可以访问所有相互信任的应用系统,Redis Session共享是实现单点登录的一种方式。本文是通过Spring Boot框架集成Redis缓存来实现session共享的,分享给大家仅供参考和学习。
有些人可能是初级Java工程师甚至刚刚接触Java编程,因此先普及一下Session的概念:Session是服务器端的一个key-value的数据结构,开发者经常把Session与cookie配合使用,用于保持登录用户的回话。
当客户端在第一次访问服务端时,服务端会响应一个sessionId并且将它存入到本地cookie中,之后每次访问都会将cookie中的sessionId放入到请求头中去请求服务器。如果通过这个sessionid无法找到对应的值,那么服务器会创建一个新的sessionid并且响应给客户端。
本文在前一篇“Spring Boot从入门到精通(六)集成Redis实现缓存机制”文章中的项目源码基础上(关注“Java精选”微信公众号,切换至后台->聚合->开源项目,可以查看Spring Boot系列从入门到精通教程),使用Spring Boot框架集成Redis缓存来实现session共享。Maven项目pom.xml文件在Spring Boot项目中pom.xml文件中,增加配置信息如下:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
配置Redis缓存类文件
在前一篇文章源码的基础上(文章末尾有Spring Boot从入门到精通系列文章地址),集成Redis实现缓存机制的源码的基础上增加@EnableRedisHttpSession即可,具体代码如下:
package com.yoodb.study.demo04.datasource; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
public class RedisConfig extends CachingConfigurerSupport { @Bean("redisTemplate")
@ConfigurationProperties(prefix="spring.redis")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory); //将key的序列化设置成StringRedisSerializer
StringRedisSerializer keySerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(keySerializer);
redisTemplate.setHashKeySerializer(keySerializer); redisTemplate.afterPropertiesSet();
return redisTemplate;
} }
@EnableRedisHttpSession:开启Session共享功能。使用此注解之后Session调用会自动通过Redis存储和获取。另外,想要达到Session共享的目的,在其他的系统上只需要做同样的配置即可。
其中maxInactiveIntervalInSeconds参数是设置Session失效时间,使用Redis
Session之后,原Spring Boot的server.session.timeout属性不再生效。
Spring Session Redis的源码分析打开@EnableRedisHttpSession注解源码如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.session.data.redis.config.annotation.web.http; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.session.FlushMode;
import org.springframework.session.SaveMode;
import org.springframework.session.data.redis.RedisFlushMode; @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({RedisHttpSessionConfiguration.class})
@Configuration(
proxyBeanMethods = false
)
public @interface EnableRedisHttpSession { //Session默认过期时间,秒为单位,默认30分钟
int maxInactiveIntervalInSeconds() default 1800;
//配置key的namespace,默认的是spring:session,如果不同的应用共用一个redis,应该为应用配置不同的namespace,这样才能区分这个Session是来自哪个应用。
String redisNamespace() default "spring:session"; //配置刷新Redis中Session的方式,默认是ON_SAVE模式,只有当Response提交后才会将Session提交到Redis
//此模式也可以配置成IMMEDIATE模式,这样的话所有对Session的更改都会立即更新到Redis。
/** @deprecated */
@Deprecated
RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE; FlushMode flushMode() default FlushMode.ON_SAVE;
//清理过期Session的定时任务默认0,到时间自动清理。
String cleanupCron() default "0 * * * * *"; SaveMode saveMode() default SaveMode.ON_SET_ATTRIBUTE;
}
Controller类文件
前一篇项目源码的基础上,在BootUserController类文件中增加两个方法,具体代码如下:
package com.yoodb.study.demo04; import java.util.HashMap;
import java.util.List;
import java.util.Map; import com.yoodb.study.demo04.bean.BootUser;
import com.yoodb.study.demo04.service.BootUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController
@RequestMapping("/myt")
public class BootUserController {
@Autowired
private BootUserService service; @RequestMapping("/getUsers")
public List<BootUser> getUsers() {
List<BootUser> list = service.getUsers();
return list;
} @GetMapping(value = "/first")
public Map<String, Object> firstResp (HttpServletRequest request){
Map<String, Object> map = new HashMap<>();
StringBuffer requestUrl = request.getRequestURL();
request.getSession().setAttribute("requestUrl",requestUrl );
map.put("requestUrl", requestUrl);
return map;
} @GetMapping(value = "/sessions")
public Object sessions (HttpServletRequest request){
Map<String, Object> map = new HashMap<>();
map.put("sessionId", request.getSession().getId());
map.put("message", request.getSession().getAttribute("requestUrl"));
return map;
} }
Spring Boot项目启动
1、访问8080端口项目启动成功之后测试访问,访问8080端口的first地址:http://localhost:8080/myt/first返回json结果:
{"requestUrl":"http://localhost:8080/myt/first"}
通过redis客户端工具连接redis服务,可以看到redis中已经存在springsession相关数据,此时也可以看到设置的sessions值。
接着,访问8080端口的sessions地址:http://localhost:8080/myt/sessions返回json结果:
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}
2、访问9090端口配置application.properties文件,请求9090端口的设置,配置信息如下:
#指定端口号
server.port=9090
项目启动成功之后测试访问,访问9090端口的sessions地址:http://localhost:9090/myt/sessions
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}
注:通过返回json结果可以发现8080与9090两个服务返回的数据相同,那么恭喜已经实现了session的共享。如果此时访问9090端口的first地址,会发现与8080端口的访问地址端口号不相同:http://localhost:9090/myt/first返回json结果:
{"requestUrl":"http://localhost:9090/myt/first"}
8080和9090端口两个服务的sessions访问地址,都会返回如下json结果:
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}
结论:两个服务的访问地址不相同,但获取的session数据相同,说明已经实现了session共享,与前面说到的登录用户只需要登录验证一次就可以访问所有相互信任的应用系统呼应了。本文“Spring Boot从入门到精通(七)集成Redis实现Session共享”文章的项目源码(springboot-study-demo04)地址:项目地址:https://github.com/yoodb/springboot
本文转自:https://blog.yoodb.com/yoodb/article/detail/1571
Spring Boot集成Redis缓存实现session的共享就是这么简单。虽说简单,但在实际项目开发中还是比较应用广泛的,尤其是在分布式应用方面,通过Redis session共享与nginx负载均衡配合,实现分布式应用。下面大家不妨试一试,有什么疑问欢迎下方留言,看到后小编立马回复!
单点登录(SSO)是指在多个应用系统中,登录用户只需要登录验证一次就可以访问所有相互信任的应用系统,Redis Session共享是实现单点登录的一种方式。本文是通过Spring Boot框架集成Redis缓存来实现session共享的,分享给大家仅供参考和学习。

有些人可能是初级Java工程师甚至刚刚接触Java编程,因此先普及一下Session的概念:Session是服务器端的一个key-value的数据结构,开发者经常把Session与cookie配合使用,用于保持登录用户的回话。
当客户端在第一次访问服务端时,服务端会响应一个sessionId并且将它存入到本地cookie中,之后每次访问都会将cookie中的sessionId放入到请求头中去请求服务器。如果通过这个sessionid无法找到对应的值,那么服务器会创建一个新的sessionid并且响应给客户端。
本文在前一篇“Spring Boot从入门到精通(六)集成Redis实现缓存机制”文章中的项目源码基础上(关注“Java精选”微信公众号,切换至后台->聚合->开源项目,可以查看Spring Boot系列从入门到精通教程),使用Spring Boot框架集成Redis缓存来实现session共享。
Maven项目pom.xml文件
在Spring Boot项目中pom.xml文件中,增加配置信息如下:
|
1
2
3
4
|
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> |
配置Redis缓存类文件
在前一篇文章源码的基础上(文章末尾有Spring Boot从入门到精通系列文章地址),集成Redis实现缓存机制的源码的基础上增加@EnableRedisHttpSession即可,具体代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package com.yoodb.study.demo04.datasource;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.cache.annotation.CachingConfigurerSupport;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;@Configuration@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)public class RedisConfig extends CachingConfigurerSupport { @Bean("redisTemplate") @ConfigurationProperties(prefix="spring.redis") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){ RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); //将key的序列化设置成StringRedisSerializer StringRedisSerializer keySerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(keySerializer); redisTemplate.setHashKeySerializer(keySerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } } |
@EnableRedisHttpSession:开启Session共享功能。使用此注解之后Session调用会自动通过Redis存储和获取。另外,想要达到Session共享的目的,在其他的系统上只需要做同样的配置即可。
其中maxInactiveIntervalInSeconds参数是设置Session失效时间,使用Redis
Session之后,原Spring Boot的server.session.timeout属性不再生效。
Spring Session Redis的源码分析
打开@EnableRedisHttpSession注解源码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package org.springframework.session.data.redis.config.annotation.web.http;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.session.FlushMode;import org.springframework.session.SaveMode;import org.springframework.session.data.redis.RedisFlushMode;@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Documented@Import({RedisHttpSessionConfiguration.class})@Configuration( proxyBeanMethods = false)public @interface EnableRedisHttpSession {//Session默认过期时间,秒为单位,默认30分钟 int maxInactiveIntervalInSeconds() default 1800;//配置key的namespace,默认的是spring:session,如果不同的应用共用一个redis,应该为应用配置不同的namespace,这样才能区分这个Session是来自哪个应用。 String redisNamespace() default "spring:session";//配置刷新Redis中Session的方式,默认是ON_SAVE模式,只有当Response提交后才会将Session提交到Redis //此模式也可以配置成IMMEDIATE模式,这样的话所有对Session的更改都会立即更新到Redis。 /** @deprecated */ @Deprecated RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE; FlushMode flushMode() default FlushMode.ON_SAVE;//清理过期Session的定时任务默认0,到时间自动清理。 String cleanupCron() default "0 * * * * *"; SaveMode saveMode() default SaveMode.ON_SET_ATTRIBUTE;} |
Controller类文件
前一篇项目源码的基础上,在BootUserController类文件中增加两个方法,具体代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
package com.yoodb.study.demo04;import java.util.HashMap;import java.util.List;import java.util.Map;import com.yoodb.study.demo04.bean.BootUser;import com.yoodb.study.demo04.service.BootUserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;@RestController@RequestMapping("/myt")public class BootUserController { @Autowired private BootUserService service; @RequestMapping("/getUsers") public List<BootUser> getUsers() { List<BootUser> list = service.getUsers(); return list; } @GetMapping(value = "/first") public Map<String, Object> firstResp (HttpServletRequest request){ Map<String, Object> map = new HashMap<>(); StringBuffer requestUrl = request.getRequestURL(); request.getSession().setAttribute("requestUrl",requestUrl ); map.put("requestUrl", requestUrl); return map; } @GetMapping(value = "/sessions") public Object sessions (HttpServletRequest request){ Map<String, Object> map = new HashMap<>(); map.put("sessionId", request.getSession().getId()); map.put("message", request.getSession().getAttribute("requestUrl")); return map; }} |
Spring Boot项目启动
1、访问8080端口项目启动成功之后测试访问,访问8080端口的first地址:http://localhost:8080/myt/first
返回json结果:
|
1
|
{"requestUrl":"http://localhost:8080/myt/first"} |
通过redis客户端工具连接redis服务,可以看到redis中已经存在springsession相关数据,此时也可以看到设置的sessions值。

接着,访问8080端口的sessions地址:
http://localhost:8080/myt/sessions
返回json结果:
|
1
|
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"} |
2、访问9090端口
配置application.properties文件,请求9090端口的设置,配置信息如下:
|
1
2
|
#指定端口号server.port=9090 |
项目启动成功之后测试访问,访问9090端口的sessions地址:
http://localhost:9090/myt/sessions
|
1
|
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"} |
注:通过返回json结果可以发现8080与9090两个服务返回的数据相同,那么恭喜已经实现了session的共享。
如果此时访问9090端口的first地址,会发现与8080端口的访问地址端口号不相同:
http://localhost:9090/myt/first
返回json结果:
|
1
|
{"requestUrl":"http://localhost:9090/myt/first"} |
8080和9090端口两个服务的sessions访问地址,都会返回如下json结果:
|
1
|
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"} |
结论:两个服务的访问地址不相同,但获取的session数据相同,说明已经实现了session共享,与前面说到的登录用户只需要登录验证一次就可以访问所有相互信任的应用系统呼应了。
本文“Spring Boot从入门到精通(七)集成Redis实现Session共享”文章的项目源码(springboot-study-demo04)地址:
https://github.com/yoodb/springboot
Spring Boot集成Redis缓存实现session的共享就是这么简单。虽说简单,但在实际项目开发中还是比较应用广泛的,尤其是在分布式应用方面,通过Redis session共享与nginx负载均衡配合,实现分布式应用。下面大家不妨试一试,有什么疑问欢迎下方留言,看到后小编立马回复!
Spring Boot从入门到精通(七)集成Redis实现Session共享的更多相关文章
- Spring Boot从入门到精通(六)集成Redis实现缓存机制
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...
- Spring Boot从入门到精通(八)日志管理实现和配置信息分析
Spring Boot对日志的处理,与平时我们处理日志的方式完全一致,它为Java Util Logging.Log4J2和Logback提供了默认配置.对于每种日志都预先配置使用控制台输出和可选的文 ...
- Spring Boot从入门到精通(五)多数据源配置实现及源码分析
多数据源配置在项目软件中是比较常见的开发需求,Spring和Spring Boot中对此都有相应的解决方案可供大家参考.在Spring Boot中,如MyBatis.JdbcTemplate以及Jpa ...
- Spring Boot从入门到精通(二)配置GitHub并上传Maven项目
简单介绍一下GitHub,它是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线,除了Git代码仓库托管 ...
- Spring Boot从入门到精通(九)整合Spring Data JPA应用框架
JPA是什么? JPA全称Java Persistence API,是Sun官方提出的Java持久化规范.是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. ...
- Spring Boot从入门到精通(十一)集成Swagger框架,实现自动生成接口文档
Swagger是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.Swagger 是一组开源项目,其中主要要项目如下: Swagger-tools:提供各种与S ...
- 快速开发架构Spring Boot 从入门到精通 附源码
导读 篇幅较长,干货十足,阅读需花费点时间.珍惜原创,转载请注明出处,谢谢! Spring Boot基础 Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计 ...
- Spring Boot从入门到精通(一)搭建第一个Spring Boot程序
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过 ...
- Spring Boot 项目实战(四)集成 Redis
一.前言 上篇介绍了接口文档工具 Swagger 及项目监控工具 JavaMelody 的集成过程,使项目更加健壮.在 JAVA Web 项目某些场景中,我们需要用缓存解决如热点数据访问的性能问题,业 ...
随机推荐
- springboot学习笔记:12.解决springboot打成可执行jar在linux上启动慢的问题
有时候,当你把你的springboot项目打成可执行的jar,放在linux上启动时,发现启动超级慢: 这往往是因为springboot内置tomcat启动时实例化SecureRandom对象随机数策 ...
- 项目中docker swarm实践
docker swarm 集群服务通信 前置要求 服务需要在同一个docker swarm集群中 服务需要处于同一个overlay网络上 服务需要暴露容器端口 有2个以上服务名不同的服务 服务部署流程 ...
- as和强制类型转换的区别
之前一直以为as就是强制类型转换,只是as是AS3中新的语法,之前用在有继承关系的对象之间的转换也无甚区别,但是今天却让我领悟到了它俩之间的区别. 原起:今天要给ColorPicker控件动态赋值,它 ...
- OpenAL介绍
OpenAL(Open Audio Library)是自由软件界的跨平台音效API,由Loki Software,使用在Windows.Linux 系统上,用在音效缓冲和收听中编码. OpenAL设计 ...
- 文件加密,密码加密,os模块
序列化模块 (非常非常重要) 序列化:将一个数据结构(list,dict....)转化成一个特殊的序列(特殊的字符串)的过程. # l1 = [1, 2, 3] # ret = str(l1) # p ...
- Android7.0 USBCamera设备/dev/video0无读权限
Android7.0的系统,具备root权限,执行 # adb shell # su # chmod 777 /dev/video0 在5.0的系统中可以预览图像,7.0返回无读权限 File fil ...
- 推荐几款开源的js日期控件
做为一个正规的网站,经常需要一些日期或时间的筛选,所以我们今天就推荐二十多款javascript的js日期/时间筛选插件.个个经典,绝对有你需要的. My97DatePicker ,国人开发的一款js ...
- VSAN磁盘扩容与收缩
删除闪存盘后,整个磁盘组都会被删除 假如一个磁盘组里面只有一块HDD盘,删除此HDD盘,磁盘组也只接被删除 可以整体删除整个磁盘组
- [LC] 225. Implement Stack using Queues
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...
- 基于OpenDDS应用程序开发(3)订阅端实现
连续的三篇博文演示如何基于OpenDDS开发应用程序,将数据从发布端节点发送到订阅端节点,该示例程序由一个发布者发布数据,一个订阅者订阅数据,使用默认的QoS策略和TCP/IP传输方式. 本文是第三篇 ...