¿Cómo puede el servidor enviar cambios asincrónicos a una página HTML creada por JSF?

Resuelto Rohit Banga asked hace 14 años • 4 respuestas

Cuando creamos una página JSF, una solicitud de cliente permite la generación de HTML dinámicamente utilizando una combinación de código Java y HTML. ¿Podemos introducir enlaces en la página HTML utilizando el marco JSF, que permiten al servidor actualizar la página HTML en función de eventos asincrónicos que ocurren más tarde en el servidor, generalmente a través de diferentes subprocesos?

Rohit Banga avatar Sep 24 '10 20:09 Rohit Banga
Aceptado

JSF 2.3+

Puedes usar @Pushy<f:websocket> para esto. A continuación se muestra un ejemplo inicial con un socket con ámbito de aplicación que actualiza una tabla de datos ante un evento activado por el backend a través del Event#fire()cual se administra el bean @Observes.

<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.getEvent().fire(newNotification);
    }

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

}

JSF 2.2-

Si aún no tienes JSF 2.3, debes dirigirte a bibliotecas JSF de terceros.

  • OmniFaces tiene <o:socket>(JSR356 WebSocket + CDI)
  • PrimeFaces tenía <p:socket>(Atmósfera)
  • ICEfaces tenía "ICEpush" (encuesta larga)

Cabe señalar que <o:socket>fue la base del JSF 2.3 <f:websocket>. Entonces, si has encontrado muchas similitudes, entonces es correcto.

PrimeFaces usa Atmosphere bajo el capó (lo cual es problemático de configurar sin Maven). Atmosphere admite websockets con respaldo a SSE y sondeo prolongado. ICEfaces se basa en una antigua técnica de sondeo largo . Ninguno de ellos implementa la API WebSocket JSR356 nativa que se introdujo más tarde en Java EE 7.

OmniFaces utiliza la API WebSocket JSR356 nativa (compatible con todos los servidores Java EE 7 y Tomcat 7.0.27+). Por lo tanto, también es más sencillo de configurar y usar (un JAR, un parámetro de contexto, una etiqueta y una anotación). Solo requiere CDI (no es difícil de instalar en Tomcat ), pero le permite incluso insertar desde un artefacto que no sea JSF (por ejemplo, un archivo @WebServlet). Por razones de seguridad y de mantenimiento del estado de la vista JSF, solo admite inserción unidireccional (servidor a cliente), no al revés. Para eso puedes seguir usando JSF ajax de la forma habitual. JSF 2.3 <f:websocket>se basa en gran medida en OmniFaces <o:socket>, por lo que encontrará muchas similitudes en sus API ( JSF - OmniFaces ).

Alternativamente, también puedes utilizar el sondeo en lugar de presionar. Prácticamente todas las bibliotecas de componentes JSF compatibles con ajax tienen un <xxx:poll>componente, como PrimeFaces con <p:poll>. Esto le permite enviar cada X segundos una solicitud ajax al servidor y actualizar el contenido cuando sea necesario. Sólo que es menos eficiente que empujar.

Ver también:

  • Cómo monitorear el estado del hilo asíncrono/en segundo plano y recibir notificaciones en un componente JSF
  • Actualizaciones en tiempo real desde la base de datos usando JSF/Java EE
  • Notificar solo a usuarios específicos a través de WebSockets, cuando se modifica algo en la base de datos.
BalusC avatar Sep 24 '2010 13:09 BalusC