Подтвердить что ты не робот

Как сервер может вызывать асинхронные изменения на HTML-странице, созданной JSF?

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

4b9b3361

Ответ 1

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 использует Atmosphere под капотами (что неудобно для настройки без Maven). Атмосфера поддерживает websockets с возвратом 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 (например, a @WebServlet). В целях безопасности и безопасности JSF, он поддерживает только односторонний push (от сервера к клиенту), а не наоборот. Для этого вы можете использовать JSF ajax обычным способом. JSF 2.3 <f:websocket> в значительной степени основан на OmniFaces <o:socket>, поэтому вы найдете много общего в своих API-интерфейсах (JSF - OmniFaces).

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

См. также:

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

Вы ничего не можете нажать. Вам необходимо опросить данные из вашего кода клиента. Веб-компоненты создают страницу, а затем завершаются. Он не предназначен для работы в поисках новых данных, чтобы подтолкнуть их к клиенту.

Возможно, ваше приложение не просто написать в виде веб-приложения. Я бы попробовал апплет, подключенный к серверному порту, чтобы получать новые события, возможно, используя JMS. См. Статью http://it.toolbox.com/blogs/enterprise-web-solutions/applet-and-jms-using-glassfish-and-jdk-6-34816