Comment le serveur peut-il pousser des changements asynchrones vers une page HTML créée par JSF?

lorsque nous créons une page JSF, une requête client permet la génération de HTML de façon dynamique en utilisant une combinaison de code Java et HTML. Pouvons-nous introduire des crochets dans la page HTML en utilisant le cadre JSF, qui permettent au serveur de mettre à jour la page HTML en fonction d'événements asynchrones se produisant plus tard sur le serveur, généralement via des threads différents?

16
demandé sur BalusC 2010-09-24 17:23:41

4 réponses

JSF 2.3+

vous pouvez utiliser @Push et <f:websocket> pour cela. Ci-dessous est un exemple de démarrage qui met à jour une table de données sur une application scoped événement lancé par le backend.

<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 -

si vous n'êtes pas encore sur JSF 2.3, vous devez vous diriger vers les bibliothèques JSF tiers.

doit être noté que le <o:socket> était la base pour le JSF 2.3 <f:websocket> . Donc, si vous avez trouvé beaucoup de similitudes, puis c'est correct.

PrimeFaces utilise Atmosphère sous le capot (qui est gênant pour le programme d'installation sans Maven). Atmosphere supporte les websockets avec repli vers L'ESS et les longs sondages. ICEfaces est basé sur l'ancienne long polling technique. Tous ceux-là n'implémentent pas l'API WebSocket native JSR356 qui n'a été introduite que plus tard dans Java EE 7.

OmniFaces utilise natif JSR356 API WebSocket (pris en charge dans tous les serveurs Java EE 7 et Tomcat 7.0.27+). Il est donc aussi plus simple de configurer et d'utiliser (un JAR, un param de contexte, une étiquette et une annotation). Il ne nécessite que le CDI (pas difficile de installer sur Tomcat ), mais il vous permet même de pousser à partir d'un artéfact non-JSF (par exemple un @WebServlet ). Pour des raisons de sécurité et de JSF view state keeping, il ne soutient une poussée à Sens Unique (du serveur au client), pas l'inverse. Pour cela, vous pouvez continuer à utiliser JSF ajax de la manière habituelle. Le JSF 2.3 <f:websocket> est largement basé sur OmniFaces <o:socket> , donc vous trouverez beaucoup de similitudes dans leurs APIs ( JSF - OmniFaces ).

alternativement, vous pouvez également utiliser le sondage au lieu de pousser. À peu près toutes les bibliothèques de composants ajax conscientes du JSF ont un composant <xxx:poll> , tel que PrimeFaces avec <p:poll> . Cela vous permet d'envoyer exery X secondes une requête ajax au serveur et de mettre à jour le contenu chaque fois que nécessaire. C'est seulement moins efficace que la pousser.

voir aussi:

19
répondu BalusC 2017-11-21 07:59:50

le plus simple pour vous peut être l'introduction de la composante "sondage" de la bibliothèque ajax4jsf: https://ajax4jsf.dev.java.net/nonav/documentation/ajax-documentation/entire.html#d0e1955

Il n'aura pas besoin de demande de reconfiguration et de gros changements dans JSF page (uniquement ajout a4j:un sondage)

cela a très bien fonctionné dans quelques-uns de mes projets.

0
répondu Andriy Sholokh 2010-09-28 20:57:08

si vous avez besoin de mises à jour cométiques complètes (Ajax inversé) et ainsi de suite, alors il vaut la peine de jeter un oeil à la bibliothèque DWR .

0
répondu Scott Wilson 2010-10-09 17:41:56

vous pouvez jeter un oeil à Couture (voir cet article pour une discussion d'utiliser couture avec JSF et AJAX).

quand j'ai utilisé Seam la dernière fois, c'était assez lent, cependant. Vous pouvez créer votre propre composant JSF qui génère JavaScript (par exemple en utilisant jQuery comme expliqué dans cet article ).

-1
répondu Aaron Digulla 2010-09-24 13:28:27