0

继续我之前的问题,我试图在应用程序的会话首次启动时初始化一个会话范围的 JSF bean,因此无论用户首先访问我的 Web 应用程序上的哪个页面,用户都可以使用该 bean。我的自定义监听器:

public class MyHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        if (FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
                .get("mySessionBean") == null) {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
                    .put("mySessionBean", new MySessionBean());
        }
    }
}

但是,这给了我一个堆栈溢出错误。似乎该类中的put()方法SessionMap试图创建一个新的HttpSession,从而导致我的侦听器发生无限循环。如何在我的应用程序会话首次启动时初始化 JSF 会话范围的 bean,而不会遇到此问题?

我正在使用 JSF 2 和 Spring 3,在 WebSphere 7 上运行。

谢谢!

4

1 回答 1

2

此时会话尚未完全完成创建。只有当侦听器方法离开时,会话才会被放入上下文中,并且可以由request.getSession()JSFgetSessionMap()在幕后使用。

相反,您应该从event参数中获取会话并使用它的setAttribute()方法。JSF 在那里查找和存储会话范围的托管 bean,如果已经存在,则不会创建新的。

public void sessionCreated(HttpSessionEvent event) {
    event.getSession().setAttribute("mySessionBean", new MySessionBean());
}

请注意,我删除了多余的 nullcheck,因为此时会话 bean不可能已经存在。


Unrelated to the concrete problem, you should actually never rely on the FacesContext being present in an implementation which isn't managed by JSF. It is quite possible that the session can be created during a non-JSF request.

于 2011-11-01T01:20:10.960 回答