jsf - 服务器如何将异步更改推送到由 JSF 创建的 HTML 页面?

标签 jsf asynchronous push

当我们创建 JSF 页面时,客户端请求允许使用 Java 代码和 HTML 的组合动态生成 HTML。
我们能否使用 JSF 框架在 HTML 页面中引入钩子(Hook),允许服务器根据服务器稍后发生的异步事件(通常通过不同的线程)更新 HTML 页面?

最佳答案

JSF 2.3+

您可以使用 @Push and <f:websocket> 为了这。下面是一个启动示例,它根据后端触发的应用程序范围事件更新数据表。

<h:dataTable id="notifications" value="#{bean.notifications}" var="notification">
    <h:column>#{notification.message}</h:column>
</h:dataTable>

<h:form>
    <f:websocket channel="push">
        <f:ajax event="updateNotifications" render=":notifications" />
    </f:websocket>
</h:form>
@Named @ApplicationScoped
public class Bean {

    private List<Notification> notifications;

    @Inject
    private NotificationService service;

    @Inject @Push
    private PushContext push;

    @PostConstruct
    public void load() {
        notifications = service.list();
    }

    public void onNewNotification(@Observes Notification newNotification) {
        notifications.add(0, newNotification);
        push.send("updateNotifications");
    }

    public List<Notification> getNotifications() {
        return notifications;
    }

}


@Stateless
public class NotificationService {

    @Inject
    private EntityManager entityManager;

    @Inject
    private BeanManager beanManager;

    public void create(String message) {
        Notification newNotification = new Notification();
        newNotification.setMessage(message);
        entityManager.persist(newNotification);
        beanManager.fireEvent(newNotification);
    }

    public List<Notification> list() {
        return entityManager
            .createNamedQuery("Notification.list", Notification.class)
            .getResultList();
    }

}

JSF 2.2-

如果您还没有使用 JSF 2.3,则需要前往第 3 方 JSF 库。
  • OmniFaces <o:socket> (JSR356 WebSocket + CDI)
  • PrimeFaces <p:socket> (气氛)
  • ICEfacesICEpush (长轮询)

  • 注意应该是<o:socket>是 JSF 2.3 <f:websocket> 的基础.因此,如果您发现了很多相似之处,那是正确的。

    PrimeFaces 使用 Atmosphere在引擎盖下(如果没有 Maven,设置起来很麻烦)。 Atmosphere 支持回退到 SSE 和长轮询的 websocket。 ICEfaces 基于古代 long polling技术。所有这些都没有实现 native JSR356 WebSocket API,后者后来才在 Java EE 7 中引入。

    OmniFaces 使用原生 JSR356 WebSocket API (在所有 Java EE 7 服务器和 Tomcat 7.0.27+ 中均受支持)。因此,它的设置和使用也是最简单的(一个 JAR、一个上下文参数、一个标签和一个注释)。它只需要 CDI(不难 install on Tomcat ),但它使您甚至可以从非 JSF 工件(例如 @WebServlet )上推送。出于安全和 JSF View 状态保持的原因,它只支持单向推送(服务器到客户端),而不支持反向推送。为此,您可以继续以通常的方式使用 JSF ajax。 JSF 2.3 <f:websocket>主要基于 OmniFaces <o:socket> ,因此您会发现它们的 API 有很多相似之处(JSF - OmniFaces)。

    或者,您也可以使用轮询而不是推送。几乎每个支持 ajax 的 JSF 组件库都有一个 <xxx:poll>组件,例如带有 <p:poll> 的 PrimeFaces .这允许您每 X 秒向服务器发送一个 ajax 请求,并在必要时更新内容。它只比推送效率低。

    也可以看看:
  • How to monitor asynchronous/background thread status and get notifications in a JSF component
  • Real time updates from database using JSF/Java EE
  • Notify only specific user(s) through WebSockets, when something is modified in the database
  • 关于jsf - 服务器如何将异步更改推送到由 JSF 创建的 HTML 页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3787514/

    相关文章:

    javascript - 在回调上运行循环,node js

    ios - 从推送通知打开应用程序时打开特定的 View Controller

    不带按钮的 JSF 显示图标

    java - JSF ViewScoped 变量无法重定向到同一页面

    java - 是否可以从 JSFManagedBean 中的 UiComponent 对象生成 Facelets 代码

    javascript - Paper.js 加载图像和事件层

    java - JSF 更新 p :selectOneMenu from another p:selectOneListbox with Ajax

    java - 使用 spring boot # SOAP Service 并行调用 SOAP 服务

    jsf - Primefaces 推送 - 仅向特定客户推送

    javascript - 如何从 ajax 将元素推送到数组 - jQuery