template etiquetas ejemplo define jsf jsf-2 java-ee-6

jsf - etiquetas - ui insert



¿Cómo manejar múltiples envíos antes de que se muestre la respuesta? (2)

Se ha informado por medio de pruebas que ocasionalmente es posible presionar un botón más de una vez si la respuesta no se procesa lo suficientemente rápido, lo que provoca varias invocaciones del código de fondo, que no queremos.

La aplicación es Java EE 6 Web Profile utilizando JSF 2.0 dentro de Glassfish 3.1.1.

Me preguntaba cómo debería abordarse esto adecuadamente , y he pensado en algunos escenarios:

  • El envío debe deshabilitar todos los botones mediante javascript mientras se procesa la respuesta.
  • Un indicador en el ámbito de la sesión que dice que ya está activo, por lo que el código confidencial se omite y simplemente pasa a la representación de la respuesta para el envío anterior.
  • Un bloque sincronizado que retrasa el procesamiento hasta que finaliza la solicitud anterior. Luego debe detectarse que ya se ha procesado y omitido.
  • ¿Utiliza uno de los ámbitos "nuevos" como la conversión para manejar la detección?

Mi sensación instintiva inmediata es que el mejor enfoque es tener bloques de código confidenciales atómicos, pero luego el problema es dar la respuesta correcta.

¿Cómo debería abordar esto?


El envío debe deshabilitar todos los botones mediante javascript mientras se procesa la respuesta.

Este es el más fácil de implementar de manera genérica. Si usa <f:ajax> exclusivamente, puede usar jsf.ajax.addOnEvent() para realizar el trabajo de forma genérica. Un enfoque alternativo de JavaScript es crear una especie de superposición de "Carga" que bloquea la interfaz de usuario para que el usuario final ya no pueda interactuar con la página subyacente. Esto es básicamente un <div> escondido absolutamente posicionado que abarca toda la ventana gráfica con cierta opacity (transparencia). Puede mostrarlo en el envío y ocultarlo en el procesamiento. La palabra clave para esta técnica es "diálogo modal" . Las bibliotecas de componentes JSF orientadas a la interfaz de usuario ya tienen al menos un componente de este tipo en su surtido. Por ejemplo, PrimeFaces con un <p:dialog modal="true"> dentro de un <p:ajaxStatus> , o el <p:blockUI>

La única desventaja es que no funcionará si el cliente tiene JS deshabilitado o no lo usa y, por lo tanto, no impedirá que los clientes HTTP presenten dos veces.

Un indicador en el ámbito de la sesión que dice que ya está activo, por lo que el código confidencial se omite y simplemente pasa a la representación de la respuesta para el envío anterior.

Esto se conoce más como "patrón de token de sincronizador" y se ha solicitado alguna vez para JSF mediante la especificación 559 que se encuentra actualmente en el ticket apuntado para 2.2, pero no parece haber actividad en él. La parte de detección y bloqueo es técnicamente fácil de implementar, pero la parte de manejo de respuesta síncrona no es fácil de implementar si se desea que el usuario final recupere finalmente la respuesta generada por la solicitud inicial. El manejo de respuesta asíncrona es fácil: simplemente no especifique ningún componente para actualizar, es decir, vacíe la colección devuelta por PartialViewContext#getRenderIds() . Después de todo, esto es más sólido que usar JS para desactivar los botones o bloquear la IU.

Hasta donde yo sé, Seam 2 fue el único que ofreció un componente JSF reutilizable para esto, el <s:token> . Sin embargo, debo admitir que esta es una idea interesante para un nuevo componente de OmniFaces . Tal vez personalmente lo echaré un vistazo.

Un bloque sincronizado que retrasa el procesamiento hasta que finaliza la solicitud anterior. Luego debe detectarse que ya se ha procesado y omitido.

Esto no es fácil de implementar genéricamente, esto requeriría un cambio en todos los métodos de acción para verificar si el trabajo ya está hecho. Tampoco funcionará si la aplicación web se ejecuta en varios servidores. Un token de sincronizador es más fácil ya que se realizaría antes de invocar los métodos de acción. Un token de sincronizador también es menos costoso, ya que no se generan múltiples solicitudes en la cola, que solo costarían hilos / recursos.

¿Utiliza uno de los ámbitos "nuevos" como la conversión para manejar la detección?

Este problema no se puede resolver jugando con alcances administrados de frijol. Los alcances administrados de beans tienen un propósito diferente: el tiempo de vida de la instancia de beans.


Como Adrian mencionó, también usaría BlockUI. Hay un componente BlockUI de Primefaces. Cuando envía sus formularios a través de ajax, también puede usar una superposición durante la solicitud. Ver el estado Ajax de Primefaces para un ejemplo.