官方参考手册:https://docs.spring.io/spring-session/docs/2.2.1.RELEASE/reference/html5/#samples
整合redis手册:
1. 项目整合
1.1 依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
1.2 项目中的配置
1.2.1 必要配置
spring.session.store-type=redis # Session store type.
1.2.2 可选配置
server.servlet.session.timeout= # 配置超时时间
spring.session.redis.flush-mode=on-save # 配置刷新策略
spring.session.redis.namespace=spring:session # 配置名称空间
1.2.3 配置redis的连接信息
spring.redis.host=localhost # Redis server host.
spring.redis.password= # Login password of the redis server.
spring.redis.port=6379 # Redis server port.
1.2.4 开启session
在启动类上添加注解@EnableRedisHttpSession
1.3 Servlet容器的初始化
servlet的容器的初始化不需要我们手动配置,是通过一个叫做springSessionRepositoryFilter的过滤器来实现的,看官方介绍:
1.4 使用
使用起来很简单,直接跟传统的HTTPSession使用方式一样即可。例如:
这样,登录成功之后,session就成功的保存到redis了,如图:
1.5 其他服务使用session
其他服务使用session,需要将经过三步:
1)引入依赖
2)配置session类型为redis
spring.session.store-type=redis
3) 在启动类上添加注解@EnableRedisHttpSession
注意:其他服务同时也需要引入redis
1.6 测试
在认证服务登录成功之后,session成功的保存到redis,同时在认证服务页面可以看到浏览器缓存的session,如图:
这时候,保存在cookie中的不再是jsessionid而是session了。
然后在打开其他服务,发现cookie中的内容为空,这时候因为,默认存的session其domain是当前系统的域名 ,需要改成子域名的形式,当我们手动将认证服务的domain值改成子域名的形式,如图:
再次进入其他服务,发现cookie中已经有了该session,同时,页面也可以获取到session,如图:
页面显示:
说明我们的整合很成功!
注意:
1)序列化对象需要存放在公共的服务,所有用到session的服务都需要依赖该服务,否则,反序列化的时候就会报classNotFund异常
2)默认发的令牌,作用域为当前域,不能解决子域session共享问题
3)默认序列化使用JDK的序列化机制,需要每个类都实现序列化接口,感觉有点麻烦,这里可以使用JSON的序列化方式来序列化对象数据到redis
2. 解决子域session共享问题——Cookie序列化器CookieSerializer
官方也给出了解决方案:https://docs.spring.io/spring-session/docs/2.2.1.RELEASE/reference/html5/#api-cookieserializer
我们只需要给一个配置类,写上对应的配置类即可,官方配置如下;
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
return serializer;
}
在项目中只需要参考官方配置做一下微调即可
package com.bjc.gulimall.auth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* @描述:解决子域session共享问题——Cookie序列化器CookieSerializer
* @创建时间: 2021/3/7
*/
@Configuration
public class SessionConfig {
// https://docs.spring.io/spring-session/docs/2.2.1.RELEASE/reference/html5/#api-cookieserializer
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
// serializer.setCookieMaxAge(Integer.MAX_VALUE); // 设置cookie最大有效期
serializer.setCookieName("GULI_JSESSION"); // 设置cookie名称
// serializer.setCookiePath("/"); // 设置cookie路径
// serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
serializer.setDomainName("gulimall.com"); // 指定domain名称 这里直接设置成子域名即可
return serializer;
}
}
3. 修改序列化机制
在SessionConfig中添加如下配置
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
注意:方法名不能改变,官网也强调了,如图:
完整的配置如下:
package com.bjc.gulimall.auth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* @描述:解决子域session共享问题——Cookie序列化器CookieSerializer
* @创建时间: 2021/3/7
*/
@Configuration
public class SessionConfig {
// https://docs.spring.io/spring-session/docs/2.2.1.RELEASE/reference/html5/#api-cookieserializer
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
// serializer.setCookieMaxAge(Integer.MAX_VALUE); // 设置cookie最大有效期
serializer.setCookieName("GULI_JSESSION"); // 设置cookie名称
// serializer.setCookiePath("/"); // 设置cookie路径
// serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
serializer.setDomainName("gulimall.com"); // 指定domain名称 这里直接设置成子域名即可
return serializer;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
注意:因为在配置中修改了cookie的相关信息,所以其他服务读取的时候,也需要根据配置的信息来读取,所以该配置类每个服务都必须要读取到。
redis中session保存信息如下:
浏览器cookie信息如下: