Spring Boot 应用使用spring session+redis启用分布式session后,如何在配置文件里设置应用的cookiename、session超时时间、redis存储的namespace

现状

项目在使用Spring Cloud搭建微服务框架,其中分布式session采用spring session+redis 模式

需求

希望可以在配置文件(application.yml)里设置应用的cookiename、session超时时间以及redis存储的namespace

目前已知可以通过下面的方式设置session超时时间和redis存储session的namespace。

1.@EnableRedisHttpSession(maxInactiveIntervalInSeconds=3600,redisNamespace="xxx")--硬编码,自己未测试

2.使用vm参数-Dspring.session.redis.namespace=xxx来设置redis的nameapce --已测试可以生效

但这都不是我们想要的效果。。我们希望可以在配置文件里设置这些参数。

设计的配置文件的相关参数如下

app:
   product:
     session:
        redisnamespace: ${app.product.name}  #存储分布式session时redis的命名空间
        timeout: 60    #session超时时间,单位:分钟。
     cookiename: ${app.product.name}SESSION #注意每个不同的应用此cookiename应该不相同

其中

app.product.cookiename的值是希望设置的cookiename
app.product.session.timeout是希望设置的session超时时间
app.product.session.redisnamespace是希望设置的redis存储session的namespace


解决方案

在一个@Configuration类里

1.使用@Bean方式定义CookieHttpSessionStrategy 对象来解决cookiename的设置问题

2.通过@PostConstruct 方式修改RedisOperationsSessionRepository对象的session超时时间、namespace

具体代码如下:

设置cookiename

默认的cookiename是SESSION,不同的应用一般要求cookiename不相同,所以需要修改。。修改的方式可参考下文:

    //从配置里读取cookiename,如果没有配置,则使用默认的DEFAULTSESSION
    @Value("${app.product.cookiename:DEFAULTSESSION}")
    String cookieName;

    @Bean
    public CookieHttpSessionStrategy cookieHttpSessionStrategy(){
        CookieHttpSessionStrategy strategy=new CookieHttpSessionStrategy();
        DefaultCookieSerializer cookieSerializer=new DefaultCookieSerializer();
        cookieSerializer.setCookieName(cookieName);//cookies名称
        strategy.setCookieSerializer(cookieSerializer);
        return strategy;
    }

设置session超时时间(默认的超时时间是30分钟)、redis存放的namespace

具体见下文:通过@PostConstruct 方式修改RedisOperationsSessionRepository对象的属性

/**
     * 从配置的yml文件里取设置session超时时间,单位是分钟
   * 如果没配置,则默认30分钟,即1800s
     */
    @Value("${app.product.session.timeout:30}")
    int sessionTimeoutInMinuts;

    /**
     * 从配置的yml文件里取设置session存储到redis时对应的namespace
     */
    @Value("${app.product.session.redisnamespace:}")
    String redisnamespace;

    @Autowired
    private RedisOperationsSessionRepository sessionRepository;

    @PostConstruct
    private void afterPropertiesSet() {
        log.info("setting sesion 超时时间 = [{}]分钟",sessionTimeoutInMinuts);
        sessionRepository.setDefaultMaxInactiveInterval(sessionTimeoutInMinuts * 60);
        log.info("setting sesion 存储到redis时的namespace = [{}]",redisnamespace);
        sessionRepository.setRedisKeyNamespace(redisnamespace);
    }

测试代码如下:增加一个/hello的http服务来获取session,以及session的最大活跃间隔,即session超时时间。。

@GetMapping("/hello")
public String hello(){
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpSession session = servletRequestAttributes.getRequest().getSession();

        return "hello,sessonId="+session.getId()+"
"+
                "MaxInactiveInterval="+session.getMaxInactiveInterval()+" CreationTime="+session.getCreationTime()+" LastAccessedTime="+session.getLastAccessedTime();
    }

在浏览器里输入对应的url验证(见下图),并用fiddler抓包。

下图为验证结果:可见session超时时间被设置成了3600s,即60分钟。

fiddler抓包情况如下,可见cookiename修改为xxxSession。

redis里存储的namespace多了一级xxx(见下图)。。原来直接是spring.session.sessions,现在是spring.session.xxx.sessions

原文地址:https://www.cnblogs.com/codeya/p/spring_session_redis_config_cookiename_session_timeout_redis_namespace.html