2010-05-10 190 views
5

我想通過在Runnable類的run()方法調用FacesContext.getCurrentInstance()得到FacesContext空,但它返回nullFacesContext.getCurrentInstance()返回運行的類

public class Task implements Runnable { 

    @Override 
    public void run() { 
     FacesContext context = FacesContext.getCurrentInstance(); // null! 
     // ... 
    } 

} 

這是如何造成的,我該如何解決?

回答

12

FacesContext存儲爲負責哪些調用FacesServlet,所述一個負責創建FacesContext HTTP請求中的螺紋的ThreadLocal變量。這個線程通常只經過JSF託管bean方法。 FacesContext在該線程產生的其他線程中不可用。

你其實應該在其他線程中不需要它。而且,當線程啓動並獨立運行時,基礎HTTP請求將立即繼續處理HTTP響應,然後消失。無論如何,你無法對HTTP響應做些什麼。

你需要以不同的方式解決你的問題。問問自己:你需要什麼?獲取一些信息?只需將信息傳遞給Runnable即可。

以下示例假定您想要訪問線程中的某個會話作用域對象。

public class Task implements Runnable { 

    private Work work; 

    public Task(Work work) { 
     this.work = work; 
    } 

    @Override 
    public void run() { 
     // Just use work. 
    } 

} 
Work work = (Work) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("work"); 
Task task = new Task(work); 
// ... 

不過,若你最終需要例如通知客戶端線程的工作已經完成,那麼你應該尋找一個不同的解決方案。添加一個面孔消息左右。答案是使用「推」。這可以通過SSE或websockets實現。一個具體的websockets例子可以在這個相關的問題中找到:Real time updates from database using JSF/Java EE。如果您碰巧使用PrimeFaces,請參閱 <p:push>。如果你碰巧使用OmniFaces,請看<o:socket>


無關的具體問題,手動創建Runnable S和在Java EE Web應用程序手動產卵線程是驚人的。團長以下是問答&一個瞭解所有注意事項,以及如何它實際上應該這樣做: