12

I have a project with Spring Boot 1.3.3 [another stuff] and Redis configurated to manage sessions, i.e., @EnableRedisHttpSession. The application works well and stores the information on Redis regularly. The problem that I'm facing is that, different from what documentation says, whether I define or not a server.session.timeout, the Redis always is using the default value for its annotation attribute (maxInactiveIntervalInSeconds) that is: 1800

Here, the documentation that I followed: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-session.html

I've also tried the approach defined by @rwinch here https://github.com/spring-projects/spring-session/issues/110 but also without success.

Updating ......


My configuration file as requested:

#First attempt (server.session.timeout) following the Spring documentation mentioned
server:
   session:
     timeout: 10  
spring:
   #session timeout under spring (as mentioned by M Deinum in comment - unfortunately doesnt work)
   session:
     timeout: 10
   redis:
     host: 192.168.99.101
     port: 6379

Beside that, I've also tried to implement a SessionListener that was in charge of setting the timeout (something like this):

    public class SessionListener implements HttpSessionListener {
        @Value(value = "${server.session.timeout}")
        private int timeout;
        @Override
        public void sessionCreated(HttpSessionEvent event) {
            if(event!=null && event.getSession()!=null){
                event.getSession().setMaxInactiveInterval(timeout);
            }
        }
...

It still didn't result in a correct scenario. I'm really racking my brain :|


Please guys, am I missing some point? Does anyone else have faced it?

Thanks in advance.

Fernando Barbeiro
  • 762
  • 4
  • 15
  • 33

5 Answers5

6

Another solution:

@EnableRedisHttpSession
public class HttpSessionConfig {

    @Value("${server.session.timeout}")
    private Integer maxInactiveIntervalInMinutes;

    @Inject
    private RedisOperationsSessionRepository sessionRepository;

    @PostConstruct
    private void afterPropertiesSet() {
        sessionRepository.setDefaultMaxInactiveInterval(maxInactiveIntervalInMinutes * 60);
    }

In this way you use the default configuration, and just add your timeout. So you maintain the default HttpSessionListener, and you don't need to use an ApplicationListener to set the time out, just one time, in the application lifecycle.

alejandropg
  • 351
  • 3
  • 6
4

Well, just in case someone is facing the same situation, we have 2 ways to workaround:

I. Implement the following:

@EnableRedisHttpSession
public class Application {
 //some other codes here
    @Value("${spring.session.timeout}")
    private Integer maxInactiveIntervalInSeconds;
    @Bean
    public RedisOperationsSessionRepository sessionRepository( RedisConnectionFactory factory) {
        RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(factory);
        sessionRepository.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds);
        return sessionRepository;
    }

Unfortunately, I had to implement a listener in order to perform additional actions when a session expires. And, when you define a RedisOperationsSessionRepository, you don't have a HttpSessionListener anymore (instead of it, you have a SessionMessageListener, as described here: http://docs.spring.io/spring-session/docs/current/reference/html5/#api-redisoperationssessionrepository). Because of this question, the 2nd approach was required.

II. To overcome the problem:

@EnableRedisHttpSession
public class Application implements ApplicationListener{

    @Value("${spring.session.timeout}")
    private Integer maxInactiveIntervalInSeconds;

    @Autowired
    private RedisOperationsSessionRepository redisOperation;

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            redisOperation.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds);
        }
    }
    ...

Assuming that none of them are the desirable out-of-box setup, at least they allow me to continue in my PoC.

Fernando Barbeiro
  • 762
  • 4
  • 15
  • 33
  • Thanks for your sharing. 1 thing I'm confused is that why when we new a RedisOperationsSessionRepository, we cannot use `HttpSessionListener ` anymore, and why the 2nd solution can avoid that, thanks – DiveInto Aug 30 '16 at 09:22
  • Hi @DiveInto Sorry, it isn't "that fresh" in my mind anymore, however, as far as I remember, the issue was that when I changed to RedisOperationsSessionRepository my HttpSessionListener weren't accessed anymore. I think that the documentation brings a clue: RedisOperationsSessionRepository is a SessionRepository that is implemented using Spring Data’s RedisOperations. In a web environment, this is typically used in combination with SessionRepositoryFilter. The implementation supports SessionDestroyedEvent and SessionCreatedEvent through SessionMessageListener. – Fernando Barbeiro Aug 31 '16 at 12:49
  • Given that, I would have to rewrite my listener that was already done (HttpSessionListener) to be a kind of SessionMessageListener - it wasn't my desire. With the second approach I observed that my HttpSessionListener still was being accessed and it achieved what I want. I know that its confusing because they are based on the same object class. Perhaps I had mislead / misunderstood something, but later I'll try to recover my branch to test and explain it better. Let me know if (in some way) I clarified a little bit about the need to a MessageListener. – Fernando Barbeiro Aug 31 '16 at 12:57
4

You can remove EnableRedisHttpSession annotation, instead, set the property:

spring.session.store-type=redis

Both spring.session.timeout and server.servlet.session.timeout will work. Please note spring.session.timeout will override server.servlet.session.timeout per my test.

Xin Li
  • 41
  • 1
  • Great. It turns out that `EnableRedisHttpSession` annotation has higher priority than `spring.session.store-type=redis`. checking code in spring-boot and spring-data-session-data v2.7.0 – niaomingjian Mar 10 '23 at 11:19
3
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60)
Flavio Troia
  • 2,451
  • 1
  • 25
  • 27
1

Extend RedisHttpSessionConfiguration and do init in @PostConstruct method.

@Configuration
public class HttpSessionConfig extends RedisHttpSessionConfiguration {

  @Value("${spring.session.timeout}")
  private Integer sessionTimeoutInSec;
  @Value("${spring.session.redis.namespace}")
  private String sessionRedisNamespace;

  @Bean
  public LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
  }

  @PostConstruct
  public void initConfig() throws Exception {
    this.setMaxInactiveIntervalInSeconds(sessionTimeoutInSec);
    this.setRedisNamespace(sessionRedisNamespace);
  }
}
user1434702
  • 817
  • 1
  • 14
  • 33