Как сервер может отправлять асинхронные изменения на HTML-страницу, созданную JSF? - PullRequest
18 голосов
/ 24 сентября 2010

Когда мы создаем страницу JSF, клиентский запрос позволяет динамически генерировать HTML, используя комбинацию кода Java и HTML. Можем ли мы ввести хуки в HTML-страницу, используя инфраструктуру JSF, которая позволяет серверу обновлять HTML-страницу на основе асинхронных событий, происходящих позже на сервере, обычно через разные потоки?

Ответы [ 4 ]

26 голосов
/ 24 сентября 2010

JSF 2.3 +

Для этого вы можете использовать @Push и <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, вам нужно обратиться к сторонним библиотекам JSF.

Следует отметить, что <o:socket> был основой для JSF 2.3 <f:websocket>. Так что если вы нашли много общего, то это правильно.

PrimeFaces использует Атмосфера под капотами (что сложно настроить без Maven). Атмосфера поддерживает веб-сокеты с переходом на SSE и длительным опросом. ICEfaces основан на древней технике long polling . Все они не реализуют собственный API-интерфейс JSR356 WebSocket, который был представлен только позже в Java EE 7.

OmniFaces использует собственный JSR356 WebSocket API (поддерживается на всех серверах Java EE 7 и Tomcat 7.0.27+). Поэтому его также проще всего настроить и использовать (один JAR, один контекстный параметр, один тег и одна аннотация). Для этого требуется только CDI (нетрудно установить на Tomcat ), но он позволяет вам даже выдвигать артефакты не из JSF (например, @WebServlet). В целях безопасности и сохранения состояния просмотра JSF он поддерживает только одностороннюю передачу (сервер-клиент), а не наоборот. Для этого вы можете продолжать использовать JSF ajax обычным способом. JSF 2.3 <f:websocket> в основном основан на OmniFaces <o:socket>, поэтому вы обнаружите много общего в их API ( JSF - OmniFaces ).

Кроме того, вы также можете использовать опрос вместо нажатия. Практически каждая библиотека JSF, поддерживающая ajax, имеет компонент <xxx:poll>, такой как PrimeFaces с <p:poll>. Это позволяет отправлять каждые X секунд ajax-запрос на сервер и обновлять содержимое при необходимости. Это только менее эффективно, чем толчок.

Смотри также:

0 голосов
/ 09 октября 2010

Если вам нужны полнофункциональные обновления Comet (обратный Ajax) и т. Д., То стоит взглянуть на библиотеку DWR .

0 голосов
/ 29 сентября 2010

Самым простым для вас может быть введение компонента «poll» библиотеки ajax4jsf: https://ajax4jsf.dev.java.net/nonav/documentation/ajax-documentation/entire.html#d0e1955

Для этого не потребуется перенастройка приложения и большие изменения на странице JSF (только добавление компонента a4j: poll)

Это очень хорошо сработало в нескольких моих проектах.

0 голосов
/ 24 сентября 2010

Вы можете взглянуть на Seam (см. в этой статье для обсуждения использования Seam с JSF и AJAX).

Когда я использовал Seam в последний раз, он был довольно медленным. Возможно, вы захотите создать свой собственный компонент JSF, который генерирует JavaScript (например, используя jQuery, как описано в этой статье ).

...