spring-session + redis 保存会话 session

基于spring-boot + spring-session + redis 实现 session 共享

依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot-starter-data-redis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>${spring-session-data-redis.version}</version>
</dependency>

spring-boot 1.x

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;
import org.springframework.session.web.http.CookieHttpSessionStrategy;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.HttpSessionStrategy;

/**
* 使用 redis 存储 HttpSession
* <pre>
* spring-boot 两种方式启用 spring-session + redis
* 1、使用 @EnableRedisHttpSession 注解,需要在注解配置 session 失效时间,使用注解 spring.session.timeout 会无效
* 2、在application.properties 配置 spring.session.store-type: redis
* 优先级:@EnableRedisHttpSession > application.properties
* </pre>
*
* @author Created by YL on 2018/11/7
*/
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400)
public class RedisHttpSessionConfig {
/**
* disable sessions expire event notifications
*/
@Bean
public ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}

/**
* spring-session 使用 fastjson 序列化
* <p>bean name 要配置成 <strong>springSessionDefaultRedisSerializer</strong>,否则不生效,参考:
* {@link RedisHttpSessionConfiguration#setDefaultRedisSerializer(org.springframework.data.redis.serializer.RedisSerializer)}</p>
*/
@Bean
@Qualifier("springSessionDefaultRedisSerializer")
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericFastJsonRedisSerializer();
}

/**
* cookie serializer
* <p>
* {@link SpringHttpSessionConfiguration#setCookieSerializer(org.springframework.session.web.http.CookieSerializer)}
*/
@Bean
@Qualifier("cookieSerializer")
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("x-auth-token");
// serializer.setDomainName("localhost");
// serializer.setDomainNamePattern("(\\w+)");//("^.+?\\.(\\w+\\.[a-z]+)$");
serializer.setCookiePath("/");
serializer.setUseHttpOnlyCookie(true);
// 由于spring-boot 1.x和2.x这个默认值不一样,所以统一设置成 false
serializer.setUseBase64Encoding(false);
// 防止 http、https 混用的情况
serializer.setUseSecureCookie(false);
return serializer;
}

/**
* HttpSessionStrategy
* <p>
* {@link SpringHttpSessionConfiguration#setHttpSessionStrategy(org.springframework.session.web.http.HttpSessionStrategy)}
*/
@Bean
@Qualifier("httpSessionStrategy")
public HttpSessionStrategy httpSessionStrategy() {
CookieHttpSessionStrategy strategy = new CookieHttpSessionStrategy();
strategy.setCookieSerializer(cookieSerializer());
return strategy;
}

// /**
// * HttpSessionStrategy
// * <p>
// * {@link SpringHttpSessionConfiguration#setHttpSessionStrategy(org.springframework.session.web.http
// .HttpSessionStrategy)}
// */
// @Bean
// @Qualifier("httpSessionStrategy")
// public HttpSessionStrategy httpSessionStrategy() {
// HeaderHttpSessionStrategy strategy = new HeaderHttpSessionStrategy();
// strategy.setHeaderName(UTConst.COOKIE_NAME);
// return strategy;
// }
}

spring-boot 2.x

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.HttpSessionIdResolver;

/**
* 使用 redis 存储 HttpSession
* <pre>
* spring-boot 两种方式启用 spring-session + redis
* 1、使用 @EnableRedisHttpSession 注解,需要在注解配置 session 失效时间,使用注解 spring.session.timeout 会无效
* 2、在application.properties 配置 spring.session.store-type: redis
* 优先级:@EnableRedisHttpSession > application.properties
* </pre>
*
* @author Created by YL on 2018/11/7
*/
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400)
public class RedisHttpSessionConfig {
/**
* disable sessions expire event notifications
*/
@Bean
public ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}

/**
* spring-session 使用 fastjson 序列化
* <p>bean name 要配置成 <strong>springSessionDefaultRedisSerializer</strong>,否则不生效,参考:
* {@link RedisHttpSessionConfiguration#setDefaultRedisSerializer(RedisSerializer)}</p>
*/
@Bean
@Qualifier("springSessionDefaultRedisSerializer")
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericFastJsonRedisSerializer();
}

/**
* cookie serializer
* <p>
* {@link SpringHttpSessionConfiguration#setCookieSerializer(CookieSerializer)}
*/
@Bean
@Qualifier("cookieSerializer")
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("x-auth-token");
// serializer.setDomainName("localhost");
// serializer.setDomainNamePattern("(\\w+)");//("^.+?\\.(\\w+\\.[a-z]+)$");
serializer.setCookiePath("/");
serializer.setUseHttpOnlyCookie(true);
// 由于spring-boot 1.x和2.x这个默认值不一样,所以统一设置成 false
serializer.setUseBase64Encoding(false);
// 防止 http、https 混用的情况
serializer.setUseSecureCookie(false);
return serializer;
}

/**
* HttpSessionIdResolver
* <p>
* {@link SpringHttpSessionConfiguration#setHttpSessionIdResolver(HttpSessionIdResolver)}
*/
@Bean
@Qualifier("httpSessionIdResolver")
public HttpSessionIdResolver httpSessionIdResolver() {
CookieHttpSessionIdResolver resolver = new CookieHttpSessionIdResolver();
resolver.setCookieSerializer(cookieSerializer());
return resolver;
}

// /**
// * HttpSessionIdResolver
// * <p>
// * {@link SpringHttpSessionConfiguration#setHttpSessionIdResolver(HttpSessionIdResolver)}
// */
// @Bean
// @Qualifier("httpSessionIdResolver")
// public HttpSessionIdResolver httpSessionIdResolver() {
// return new HeaderHttpSessionIdResolver("x-gdwxkf-token");
// }
}

问题

应用容器 session 过期时间

1
2
3
4
server:
servlet:
session:
timeout: 1d
  • server.servlet.session.timeout参数对于SpringBoot内嵌的Tomcat生效。

  • 如果项目部署在外部Tomcat中,该参数对外部Tomcat不生效。

    外部Tomcat部署可以这样配置session过期时间

    • 第一种:在web.xml

      1
      2
      3
      <session-config>
      <session-timeout>30</session-timeout>
      </session-config>
    • 第二种:在Tomcatconf/server.xml

      1
      <Context path="/app" docBase="/app" defaultSessionTimeOut="86400" .../>
    • 第三种:在Java程序中

      1
      session.setMaxInactiveInterval(86400);
  • 本文作者: forever杨
  • 本文链接: https://blog.yl-online.top/posts/74b23c9e.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。如果文章内容对你有用,请记录到你的笔记中。本博客站点随时会停止服务,请不要收藏、转载!