spring-session-data-redis对接过程中遇到的问题
1:多redis环境问题
背景:因为我这个项目是单独的jar包,需要独立与系统之外,所以存在项目中有多个redis环境配置的问题
1.1、正确的配置方式:
//spring-session-data-redis配置
@Configuration @EnableRedisHttpSession //指定spring-session-data-redis使用哪个方式 static class QualifiedConnectionFactoryRedisConfig { @Bean @SpringSessionRedisConnectionFactory public RedisConnectionFactory qualifiedRedisConnectionFactory() { return mockRedisConnectionFactory(); }
//设置cookie
@Bean
public DefaultCookieSerializer defaultCookieSerializer() {
DefaultCookieSerializer cookieSerializer = new NonWriteCookieSerializer();
cookieSerializer.setDomainNamePattern(pattern);
cookieSerializer.setUseBase64Encoding(false);
return cookieSerializer;
}
//设置序列化方式
@Bean("springSessionDefaultRedisSerializer")
public RedisSerializer<Object> redisSerializer() {
return new NullableJdkSerializationRedisSerializer();
}
public static class NullableJdkSerializationRedisSerializer extends JdkSerializationRedisSerializer {
@Override
public Object deserialize(byte[] bytes) {
try {
return super.deserialize(bytes);
} catch (Exception e) {
return null;
}
}
}
}
//项目redis @Configuration static class PrimaryConnectionFactoryRedisConfig { @Bean @Primary public RedisConnectionFactory primaryRedisConnectionFactory() { return mockRedisConnectionFactory(); } }
2.1、关于注解:@SpringSessionRedisConnectionFactory的使用
加了该注解,spring-data-redis-session会默认去找该redis的配置,如果找不到才会去容器里面加载其他的缓存,所以当有多个redis的时候,尽量有个主redis配置,源码如下:
该配置在:spring-session-data-redis包下的RedisWebSessionConfiguration类中
@Autowired public void setRedisConnectionFactory(@SpringSessionRedisConnectionFactory ObjectProvider<ReactiveRedisConnectionFactory> springSessionRedisConnectionFactory, ObjectProvider<ReactiveRedisConnectionFactory> redisConnectionFactory) { ReactiveRedisConnectionFactory redisConnectionFactoryToUse = (ReactiveRedisConnectionFactory)springSessionRedisConnectionFactory.getIfAvailable(); if (redisConnectionFactoryToUse == null) { redisConnectionFactoryToUse = (ReactiveRedisConnectionFactory)redisConnectionFactory.getObject(); } this.redisConnectionFactory = redisConnectionFactoryToUse; }
//设置redis的序列化方式
@Autowired(
required = false
)
@Qualifier("springSessionDefaultRedisSerializer")
public void setDefaultRedisSerializer(RedisSerializer<Object> defaultRedisSerializer) {
this.defaultRedisSerializer = defaultRedisSerializer;
}
3.关于spring-session-data-redis部分参数失效问题
3.1:可以看下这篇博客:https://zhuanlan.zhihu.com/p/414683027
背景:使用该框架,发现redis中所有的属性都有的,比如:sessionAttr中有user对象字段,也有remark:字符串。发现在使用方只能拿到remark,却拿不到user对象。
原因:这是因为该框架的设计者,使用的是jdk的序列化方式,比较简单那粗暴,导致原来的user对象找不到,在jar包中拿不到就直接过滤了,所以看到缓存中就不存在该对象了。
public MapSession(Session session) { this.sessionAttrs = new HashMap(); this.creationTime = Instant.now(); this.lastAccessedTime = this.creationTime; this.maxInactiveInterval = Duration.ofSeconds(1800L); if (session == null) { throw new IllegalArgumentException("session cannot be null"); } else { this.id = session.getId(); this.originalId = this.id; this.sessionAttrs = new HashMap(session.getAttributeNames().size()); Iterator var2 = session.getAttributeNames().iterator(); while(var2.hasNext()) { String attrName = (String)var2.next(); Object attrValue = session.getAttribute(attrName); if (attrValue != null) { this.sessionAttrs.put(attrName, attrValue); } } this.lastAccessedTime = session.getLastAccessedTime(); this.creationTime = session.getCreationTime(); this.maxInactiveInterval = session.getMaxInactiveInterval(); } }
4:关于session失效的问题:
set-cookie
里多了一个参数,SameSite=Lax
set-cookie: SESSION=ODdmZjM1ZDAtNTNkZS00YTJjLThkOTAtNDA5OWNjNzg4ZWY4; Path=/; HttpOnly; SameSite=Lax
没错,就是多了SameSite=Lax
覆盖默认CookieSerializer
@Bean
public CookieSerializer httpSessionIdResolver(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// private String sameSite = "Lax";
cookieSerializer.setSameSite(null);
return cookieSerializer;
}
参考这篇博客:https://www.cnblogs.com/jarjune/p/11912277.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现