2

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

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

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

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

我也尝试过让 JSF 托管 bean 成为 MDB,但我做不到(看来你不能在同一个类中拥有两者?)。

由于我是 JSF 世界的初学者,我现在有点卡住了。有没有办法让它工作?

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

4

4 回答 4

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 方式的消息更新视图。

例如

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的a:

@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 注释,但它们应该足够自我解释。

于 2010-04-20T14:52:25.223 回答
1

我不是专家,但我希望 FacesContext 仅在处理 JSF 请求期间可用。恐怕你不能完全按照你的意愿去做,但你当然可以解决它。其实有两个问题:

  1. 如何通过 MDB 获取对 JSF 页面的更新?
  2. 事件发生时如何在客户端刷新页面?您通常不能将数据从服务器发送到客户端,客户端必须请求它们(尽管有一些解决方法,例如 http://en.wikipedia.org/wiki/Comet_(programming)))

我想要以下内容:

  1. 在 MDB 中,将更新的数据存储在某处 - 例如全局缓存(带有 @Singleton 和更新的集合或映射的无状态会话 bean)
  2. 修改 JSF 页面,使其定期向服务器查询更新(最好在后台通过一些启用 ajax 的 JSF 组件使用 Ajax) - 如果通过 MDB 接收到更新,服务器将返回它并且页面将重新渲染自己
于 2010-04-20T09:28:23.933 回答
0

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

于 2010-04-20T14:42:26.610 回答
0

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

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

于 2010-04-21T08:09:21.083 回答