2011-11-01 77 views
0

繼續執行我的previous question,我試圖在應用程序的會話第一次啓動時初始化會話範圍的JSF bean,因此無論哪個頁面他們首先訪問我的Web應用程序。我的自定義偵聽器:初始化HttpSessionListener中的JSF SessionScoped bean時出現StackOverflow錯誤

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()); 
     } 
    } 
} 

但是,這給我一個堆棧溢出錯誤。看起來,SessionMap類中的put()方法嘗試創建新的HttpSession,從而導致與我的偵聽器發生無限循環。當我的應用程序會話第一次啓動時,如何初始化一個JSF會話範圍的bean,而不會遇到這個問題?

我在Spring 7上使用JSF 2,運行在WebSphere 7上。

謝謝!

回答

2

該會話尚未完全完成創建。只有偵聽器方法離開時,會話纔會放入上下文中,並且由於JSF的getSessionMap()正在使用,所以request.getSession()可用。

相反,您應該從event參數中抓取會話並使用其setAttribute()方法。 JSF查找和存儲會話範圍的託管bean,如果已經存在,將不會創建新的。

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

注意,我去掉了多餘的nullcheck,因爲它是在這一點上不可能的會話bean已經存在。


無關到具體問題,您應該卻從未依靠FacesContext存在於未通過JSF管理的實現。會話可能是在非JSF請求期間創建的。