【问题标题】:session events dont work in spring session会话事件在春季会话中不起作用
【发布时间】:2017-03-26 01:04:22
【问题描述】:

我的应用程序使用 http 和 stomp over WebSocket。所以当用户使用 WebSockets 时我需要刷新我的 httpSession 所以为了不发明自行车我决定使用 Spring Session,因为这提供了 Http 和 WebSockets 之间的清晰集成。但是我遇到了一个问题。当我使用 TOMCAT SESSION 实现时,我有这个监听器:

@Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.addListener(new HttpSessionEventPublisher());
...
}

而且效果非常好。会话注册表收到一个 SessionDestroyEvent 并销毁了一个会话。

现在,使用基于 H2 的 Spring Session,它不起作用。 我尝试了这样的不同方法:

@Bean
public HttpSessionEventPublisher httpSessionPublisher() {
    return new HttpSessionEventPublisher();
}


@Bean
public HttpSessionListener httpSessionListener() {
    return new HttpSessionListener() {
        @Override
        public void sessionCreated(HttpSessionEvent se) {
            System.out.println("I EXIST");
        }

        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            System.out.println("I EXIST");
        }
    };
}

但它也不起作用。

我使用带有 H2 存储的 SpringSession,我的配置是:

@EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 15)
public class H2SessionConfig {

    @Bean(name = "session_dataSource")
    public EmbeddedDatabase dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("org/springframework/session/jdbc/schema-h2.sql").build();
    }

    @Bean
    public PlatformTransactionManager transactionManager(@Qualifier("session_dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }

    @Bean
    public HttpSessionListener httpSessionListener() {
        return new HttpSessionListener() {
            @Override
            public void sessionCreated(HttpSessionEvent se) {
                System.out.println("I EXIST");
            }

            @Override
            public void sessionDestroyed(HttpSessionEvent se) {
                System.out.println("I EXIST");
            }
        };
    }

    @Bean
    public HttpSessionEventPublisher httpSessionPublisher() {
        return new HttpSessionEventPublisher();
    }
}

提前谢谢你。

【问题讨论】:

    标签: java spring session tomcat spring-session


    【解决方案1】:

    由于 RDBMS 在这方面的明显限制,Spring Session JDBC 不支持发布会话事件。

    reference manualJdbcOperationsSessionRepository javadoc 都记录了此限制。

    【讨论】:

    • 请澄清为什么它如此明显以至于它不支持这些事件......数据库不会使会话到期。这是在 java 代码中完成的,并且 java 代码可以触发事件并为此管理侦听器。
    • 该事件需要传播到所有集群成员。为了实现这一点,您需要某种发布-订阅机制。与 Redis 或 Hazelcast 等数据存储相比,关系数据库在这方面受到限制。
    • 我不相信这是强制性的。只要一个集群成员接收到可接受的事件。我猜想在某些用例中,每个集群成员都可能喜欢该事件,但对于很多用例,只要 1 个集群成员处理该事件就足够了。
    • Spring Session 的 HttpSession 事件支持的目标一直是支持将事件传播到所有集群成员。如果没有发布-订阅机制,这是不可能的。我们也不希望出现这样一种情况,即一个特性从一个数据存储到另一个数据存储的行为根本不同,所以如果我们不能确保选择只是不支持事件。旁注:理想的会话数据存储应该能够使用基于 TTL 的机制使会话过期,并通过 pub-sub 通知应用程序。一些 SessionRepository 处理到期的事实更多的是一种解决方法。
    猜你喜欢
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多