服务器启动的渲染:EJB - > FacesContext的?

时间:2010-04-20 08:43:04

标签: java jsf ejb-3.0 icefaces jsf-2

我已经在Icefaces论坛上问了这个问题,但同时我意识到这是一个更普遍的问题。

当我在MDB中收到消息时,我想更新JSF页面的部分内容。

问题是,如何从EJB容器中获取FacesContext?

在消息处理函数中,FacesContext.getCurrentInstance()返回null。

我也试过让一个JSF托管bean成为一个MDB,但我不能(似乎你不能在同一个类中都有这两个?)。

由于我是JSF世界的初学者,我现在有点困惑。有没有办法让它发挥作用?

(Glassfish v3 + Netbeans 6.8,JSF2 + Icefaces 2.0 alpha2)

4 个答案:

答案 0 :(得分:2)

FacesContext是基于HTTP请求的,因此仅在HTTP请求处理期间可用,甚至仅在请求URL与FacesServlet的url模式匹配时才可用。如果您不在服务器执行的处理HTTP请求的线程内,那么也没有FacesContext的方法。在EJB容器中,完全没有HTTP请求的手段。

从技术上讲,让EJB通知JSF有关新消息的唯一方法是让EJB在与FacesServlet的url模式匹配的URL上发出HTTP请求,并将消息作为请求参数。您可以使用java.net.URLConnection。反过来,JSF可以像你提到的那样使用IceFaces的方式更新视图来进行Comet / HTTP推送。

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附加到支持bean,如下所示:

@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 :(得分:1)

我不是专家,但我希望FacesContext仅在处理JSF请求时可用。我担心你不能做你想要的,但你当然可以解决它。实际上有两个问题:

  1. 如何通过MDB将更新发送到JSF页面?
  2. 如何在事件发生时刷新客户端上的页面?您 无法正常地将数据从服务器发送到客户端,客户端必须 要求他们(虽然有一些解决方法,如 http://en.wikipedia.org/wiki/Comet_(programming)))
  3. 我有类似以下内容:

    1. 在MDB中,将更新的数据存储在某个地方 - 例如存储到全局缓存中(带有@Singleton的无状态会话bean以及更新的集合或映射)
    2. 修改JSF页面,以便它定期查询服务器的更新(最好是在后台使用Ajax通过一些支持Ajax的JSF组件) - 如果通过MDB收到更新,服务器将返回它并且该页面将重新呈现

答案 2 :(得分:0)

我有一个解决方法,涉及JSF端的Timer(幸运的是它只在服务器上,不需要AJAX和客户端 - 服务器通信),它会检查Singleton并在必要时触发更新。 但是我仍然认为这不是正确的解决方案,而且可以在没有Timer的情况下完成...

答案 3 :(得分:0)

我也在Icefaces论坛上得到了回复:

org.icefaces.application.PortableRenderer提供了一个可以在非JSF线程上使用的对象来调用push。 (这在svn主干中可用,将在下一个alpha(= Icefaces 2.0 alpha 3)版本中提供。)