2010-04-20 15 views
2

我已經在Icefaces論壇上問過這個問題,但同時我意識到這是一個更通用的問題。服務器啓動的渲染:EJB - > FacesContext?

我想在我的MDB中收到消息時更新部分JSF頁面。

問題是,我如何從EJB容器中獲取FacesContext?

在消息處理函數FacesContext.getCurrentInstance()中返回null。

我也試圖讓一個JSF託管bean是一個MDB,但我不能(似乎你不能在同一個類中都有)。

因爲我是JSF世界的初學者,所以我現在被卡住了。有沒有辦法讓它工作?

(Glassfish的第三版+ Netbeans的6.8,JSF2 + ICEfaces的2.0α-2)

回答

2

FacesContext是基於HTTP請求的,因此僅在HTTP請求處理期間可用,甚至只有當請求URL匹配FacesServlet的url模式。如果你不在服務器執行的處理HTTP請求的線程中,那麼也沒有FacesContext的意義。在EJB容器中,完全沒有HTTP請求的手段。

從技術上講,讓EJB通知JSF有關新消息的唯一方法是讓EJB在匹配FacesServlet的url模式的URL上發出HTTP請求,並將消息作爲請求參數。您可以使用java.net.URLConnection。然後JSF可以像所提到的那樣執行Comet/HTTP推送,像使用IceFaces方式的消息更新視圖。

E.g.

URL url = new URL("http://example.com/context/poll.jsf?msg=" + URLEncoder(msg, "UTF-8")); 
URLConenction connection = url.openConnection(); 
InputStream response = connection.getInputStream(); 

並且被附連到背襯豆這樣的poll.jsf

@ManagedBean 
public class Poll { 

    @ManagedProperty(value="#{param.msg}") 
    private String msg; 

    @PostConstruct 
    public void init() { 
     // Do something with msg. 
    } 

    public void setMsg(String msg) { 
     this.msg = msg; 
    } 

} 

注意:在使用JSF 2.0註釋,但它們應該是自我解釋足夠。

+1

謝謝你的回答。它工作,但仍然不是我認爲最乾淨的解決方案(爲什麼EE應用程序服務器沒有這樣做的內部方式,沒有從外部調用servlet?),但可以接受。 – egbokul 2010-04-21 08:05:59

1

我不是專家,但我期望在FacesContext只有一個JSF請求的處理過程中是可用的。我擔心你不能做到你想要的東西,但你肯定可以解決它。實際上有兩個問題:

  1. 如何通過MDB獲取更新到JSF頁面?
  2. 如何在事件發生時刷新客戶端頁面?您 不能正常從服務器發送數據到客戶端,客戶端必須 requst它們(雖然有一些變通方法,如 http://en.wikipedia.org/wiki/Comet_(programming)))

我倒是類似如下:

  1. 在MDB中,將更新的數據存儲在某處 - 例如存儲到全局緩存中(無狀態會話bean與@Singleton和集合或更新映射)
  2. 修改JSF頁面,以便它在服務器中查詢定期間隔(最好在酒吧第二通過一些支持Ajax的JSF及部件使用Ajax) - 如果是通過MDB接收到更新,服務器將返回它,該頁面將重新呈現自身
+0

嗨,謝謝你的答案。 #2很容易,因爲Icefaces 2.0有它的PushRenderer類,這很好。 #1是一個問題:如果我在外面,我該如何引用由FacesServlet管理的類實例? EJB運行在不同的容器中...... – egbokul 2010-04-20 10:30:27

+0

@egbokul#1根本不處理JSF,它只是將數據存儲在@Singleton會話Bean中,然後可以由JSF訪問它。所以它是JSF - > EJB,反之亦然。但是使用您提到的PortableRenderer,您可以希望將數據從MDB直接推送到JSF。我很好奇它是如何工作的:-)祝你好運! – 2010-04-22 13:03:28

0

我有上涉及計時器的解決方法JSF方面(幸運的是它僅在服務器上,不需要AJAX和客戶端 - 服務器通信),它檢查單例並在必要時觸發更新。 但是,我仍然認爲這不是一個合適的解決方案,並且它可以在沒有計時器的情況下完成...

0

我也得到了在ICEfaces的論壇的響應:

org.icefaces.application.PortableRenderer提供了可以在非JSF線程被用來調用推的對象。 (這是在svn中可用,並將在下一個阿爾法(= Icefaces 2.0 alpha 3)發佈。)