继续我的previous question,我正在尝试在应用程序的会话首次启动时初始化会话范围的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上运行。
谢谢!
答案 0 :(得分:2)
此时会话尚未完全创建。只有当侦听器方法离开时,会话才会被放入上下文中,并由request.getSession()
提供,因为JSF的getSessionMap()
正在使用。
相反,您应该从event
参数中获取会话并使用其setAttribute()
方法。 JSF在那里查找并存储会话范围的托管bean,如果已经存在则不会创建新的。
public void sessionCreated(HttpSessionEvent event) {
event.getSession().setAttribute("mySessionBean", new MySessionBean());
}
请注意,我删除了多余的nullcheck,因为那时不可能会话bean已经存在。
无关,实际上你应该永远不要依赖于不由JSF管理的实现中存在的FacesContext
。很可能会在非JSF请求期间创建会话。