0

在我们使用 JSF/PrimeFaces、Spring 和 Hibernate 的应用程序中,一旦用户登录,我们就会在数据库中设置一个标志,直到用户从应用程序注销或会话到期。问题是,即使他只是在没有正确注销的情况下关闭浏览器,我们也需要清除数据库中的这个标志。为了实现这一点,我已经尝试了 jquery$window.unload$window.bind函数,它们实际上调用了一些 JS 函数,而这些函数<p:remoteCommand>又调用了一个托管 bean 方法来清除 DB。然而,我后来才知道这是不可靠的,在测试时我们也看到事件没有持续触发。无论如何,我怎样才能实现数据库清理?

4

1 回答 1

1

在浏览器关闭时收听是不可靠的。您可以为此使用beforeunload事件,但是世界上知道的每个网络浏览器都不支持这一点,甚至最终用户可以禁用/欺骗/破解。那么我们不是在讨论触发 ajax 请求期间的竞争条件:ajax 请求会在浏览器关闭之前完全到达吗?通常情况并非如此,浏览器关闭胜过 ajax 请求。

只需在会话到期时收听服务器端即可。

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent event) {
        // NOOP.
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        // Do your job here. 
        // ...
    }

}

请注意,当您在编程注销期间显式调用ExternalContext#invalidateSession()(或)时,也会调用它。HttpSession#invalidate()

于 2013-06-19T12:01:55.800 回答