springboot的版本:<version>2.1.6.RELEASE</version>
搭建springboot框架涉及到session管理,交给springboot框架管理,同时为了以后分布式或集群等的扩展,故将session存储到Redis数据库中。
理解:: session交给spring管理, spring将session信息存储到redis数据库中,配置好相关配置就可以。至于spring怎么跟redis赋值、取值等spring框架自动去处理,不用开发者去管。
( 既然引入了redis。这里可不仅仅就存session。建一个redis的管理连接的公共类,这样其他地方就可以使用redis了(先建session相关,后面再弄这块))
一、引入maven依赖
<dependency><!--redis依赖包 --><!--spring boot 与redis应用基本环境配置 --><!--没写版本号。直接依赖spring-boot-starter-parent的了,这样避免兼容性问题--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency><!--spring-session依赖包 --><!--spring session 与redis应用基本环境配置,需要开启redis后才可以使用,不然启动Spring boot会报错 --> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
二、Redis 和 Session 配置(application.properties)
1. redis 和 redis连接池配置(application.properties)
#*************************************** Redis配置 ********************************************* # Redis数据库索引(默认为0) spring.redis.database=1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接密码(默认为空) spring.redis.password= #连接超时时间(毫秒)(不能设置太短,我之前设置为0,导致服务启动不了,报错io.lettuce.core.RedisCommandTimeoutException: Command timed out) spring.redis.timeout=5000
# ****************Redis连接池配置 #lettuce 是一个可以做缓冲池的插件,也可以不用,使用pool为三级参数,即spring.redis.pool... # 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=100 # 连接池中的最大空闲连接 spring.redis.jedis.pool.max-idle=5 # 连接池中的最小空闲连接 spring.redis.jedis.pool.min-idle=0 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedis.pool.max-wait=60000
**注:::关于springboot各个版本的redis集成,参考springboot中各个版本的redis配置问题
2.Spring Session配置
有两种方式(我用的方式一)
方式一: application.properties中配置
#*************************************** Spring Session配置 ********************************************* #spring session使用存储类型(启动Redis管理session) 《springboot默认就是使用redis方式,如果不想用可以填none》 spring.session.store-type=redis #自定义命名空间 spring.session.redis.namespace=gkzpSession #RedisFlushMode有两个参数:ON_SAVE(表示在response commit前刷新缓存),IMMEDIATE(表示只要有更新,就刷新缓存) spring.session.redis.flush-mode=on_save #session超时时间(s) (要确定服务器时间与Redis数据库服务时间同步) spring.session.timeout=1800
注:session存放在redis中的命名空间,以及
修改cookies中sessionId的名字。 参考:https://blog.51cto.com/11864647/2287402
方式二:以springboot注解的方式
package com.nsoft.gkzp.syscore.config; import org.springframework.context.annotation.Configuration; import org.springframework.session.data.redis.RedisFlushMode; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; /** * session托管到redis * */ //使用springboot-session处理,单位:秒; //maxInactiveIntervalInSeconds session超时时间(s) 1800s=30m //RedisFlushMode有两个参数:ON_SAVE(表示在response commit前刷新缓存),IMMEDIATE(表示只要有更新,就刷新缓存) //redisNamespace @Configuration @EnableRedisHttpSession(maxInactiveIntervalInSeconds=1800, redisFlushMode = RedisFlushMode.ON_SAVE, redisNamespace = "gkzpSession")//单位为秒 public class RedisSessionConfiguration { }
**重要:::spingboot服务器和redis服务器时间必须同步
springsession会拿服务器时间 跟 redis存储的时间比对,看时间差是否超时、失效。如果时间不同步,可能有些请求就会session失效,或者自己往session中存放的需手工确认失效的功能 会偶尔出错;比如:短信验证码
关于linux时间同步,请看文章:https://www.cnblogs.com/yingsong/p/9857591.html
配置成功,redis的session如下:
三、RedisTemplate之opsForValue使用说明
上面配置好后。在java中可直接用StringRedisTemplate或RedisTemplate.posForValue对redis进行操作:
.posForValue有很多命令。请查看 https://blog.csdn.net/aoxiangzhe/article/details/93164823
@Autowired StringRedisTemplate stringRedisTemplate; // k-v都是字符串 @Autowired RedisTemplate redisTemplate; // k-v都是对象 如果是对象,对象需要实现序列号,否则报错,eg:public class Employee implements Serializable {xxxx}
//序列化后,存入redis里的value值依然是乱码,其实默认的序列化是JDK的,我们需要自己优化一下,比如编程json的序列化。
json序列化参照:https://www.cnblogs.com/iceb/p/9479976.html 但用这个方式json序列号依然不起作用,后来在网上又查了其他的,配置成
package com.nsoft.gkzp.syscore.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * 使用RedisTemplate.opsForValue()方法向redis存储对象时,json串为乱码,故在这里配置下,设置序列化Key及Value的实例化对象 * @author zdyang * @date 2019.09.05 */ @Configuration public class MyRedisConfig { @Autowired private RedisTemplate redisTemplate; @Bean public RedisTemplate redisTemplateInit() { //设置序列化Key的实例化对象 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置序列化Value的实例化对象 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } }
例如:(以RedisTemplate为例)
@Autowired
private RedisTemplate redisTemplate;
SysUser sysUser = sysUserService.login(loginName, null);//账户校验 并获得其信息
redisTemplate.opsForValue().set("timeOutKey",sysUser,10, TimeUnit.SECONDS);
String timeOutValue = redisTemplate.opsForValue().get("timeOutKey")+"";
System.out.println("通过set(K key, V value, long timeout, TimeUnit unit)方法设置过期时间,过期之前获取的数据:"+timeOutValue);
Thread.sleep(5*1000);
timeOutValue = redisTemplate.opsForValue().get("timeOutKey")+"";
System.out.print(",等待10s过后,获取的值:"+timeOutValue);
生成后台 和 redis数据如下:
成功了,json串不是乱码了,但spring管的session里存储的json串依然乱码。这个后面研究这了再完善吧。
例如:(以StringRedisTemplate为例)
package com.nsoft.gkzp.system.sysuser.controller; import org.springframework.data.redis.core.StringRedisTemplate;
@Autowired
private StringRedisTemplate redisTemplate;
... ...
redisTemplate.opsForValue().set("loginUser:" +sysUser.getId(), arg0.getSession().getId());//向redis里存储 用户ID-sessionID对,用于拦截器判断是否重复登录
//这里Key值写成 "loginUser:" +sysUser.getId()。就会生成名字为loginUser的命名空间,其Key值为"loginUser:" +sysUser.getId()。如不带:的话,就不会生成命名空间
package com.nsoft.gkzp.syscore.config.interceptor; import org.springframework.data.redis.core.StringRedisTemplate;
@Autowired
private StringRedisTemplate redisTemplate;
... ...
String loginSessionId = redisTemplate.opsForValue().get("loginUser:" +userContext.getLoginUserId());//获得在redis存储的seesionID
if (loginSessionId != null && loginSessionId.equals(request.getSession().getId()))
{
return true;
}
生成一个名为loginUser的namespace中。永久保存。
在做这块的时候,参照了网上一些文章:
https://www.cnblogs.com/jpfss/p/11016400.html
https://www.cnblogs.com/yingsong/p/9838198.html
https://blog.51cto.com/11864647/2287402
本文来自博客园,作者:东方飘雪,转载请注明原文链接:https://www.cnblogs.com/zdyang/p/session.html