【问题标题】:Removing JSF managed beans on session timeout在会话超时时删除 JSF 托管 bean
【发布时间】:2015-05-18 08:59:09
【问题描述】:

我无法弄清楚如何正确处理 JSF 中会话的自动销毁。当然,此时会话会被​​容器无效化,从而导致会话范围的 bean 上也调用 @PreDestroy 方法。

在一些会话范围的 bean 的 PreDestroy 中,我们正在取消注册一些侦听器,如下所示:

@PreDestroy
public void destroy() {
    getWS().removeLanguageChangeListener(this);
}

但是,getWS() 方法实际上尝试获取对另一个会话范围 bean 的引用,但是失败了,因为 FacesContext.getCurrentInstance() 返回 null。 根据 Ryan Lubke 的说法,后者似乎是正常的 JSF 行为:

我们忠实于这里的规范。我不确定假设是否安全 FacesContext 将在所有 @PreDestroy 案例中可用。 考虑会话范围的 bean。会话可能由 容器由于不活动。 FacesContext 无法在 那个时候。

我很好,但是应该如何确保正确清除所有对象?在 PreDestroy 中删除 self 作为监听器是不好的做法吗? 或者我们是否只需要对请求/视图范围的 bean 执行此操作,因为它们的寿命比 WS 的会话范围短(来自 getWS())?

请注意,我在 Tomcat7 上会遇到此问题,但我预计每个容器都会出现此问题。

【问题讨论】:

    标签: jsf session


    【解决方案1】:

    我认为会话 bean 是在 servlet 容器上的专用线程中清理的,因此位于 FacesContext 之外(与 JSF 请求相关联)。您可以使用HttpSessionListener 来解决问题并清理会话资源。比如:

    @WebListener
    public class LifetimeHttpSessionListener implements HttpSessionListener {
    
    @Override
    public void sessionCreated(final HttpSessionEvent e) {
        // create some instance here and save it in HttpSession map
        HttpSession session = e.getSession();
        session.setAttribute("some_key", someInstance);
        // or elsewhere in JSF context:
        // FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("some_key", someInstance);
    }
    
    @Override
    public void sessionDestroyed(final HttpSessionEvent e) {
        // get resources and cleanup them here
        HttpSession session = e.getSession();
        Object someInstance = session.getAttribute("some_key");
    }
    }
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2011-12-05
      • 1970-01-01
      • 2011-09-08
      • 2010-11-12
      • 1970-01-01
      • 2014-12-18
      • 2023-03-03
      • 2013-09-24
      • 2014-06-30
      相关资源
      最近更新 更多