La presentación debe deshabilitar todos los botones mediante javascript mientras se está respondiendo.
Este es el más fácil de implementar de forma genérica. Si usa <f:ajax>
exclusivamente, puede usar jsf.ajax.addOnEvent()
para realizar el trabajo de manera 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>
oculto absolutamente posicionado que abarca toda la ventana gráfica con algo de opacity
(transparencia). Puede mostrarlo en el envío y ocultarlo en el procesamiento. La palabra clave para esta técnica es "modal dialog". Las bibliotecas de componentes JSF orientadas a la interfaz de usuario ya tienen al menos un componente de este tipo en su surtido. P.ej. PrimeFaces con un <p:dialog modal="true">
dentro de un <p:ajaxStatus>
, o la <p:blockUI>
La única desventaja es que no va a funcionar si el cliente tiene JS desactivado o no usarlo y que por lo tanto no va a evitar que los clientes HTTP desde somete dobles.
Una bandera en el ámbito de la sesión diciendo que ya está activo, por lo que el código sensibles se omite y sólo se mueve a la re-representación de la respuesta a la anterior someterse.
Esto es más conocido como "synchronizer token pattern" de los siglos se ha solicitado para JSF por spec issue 559 que actualmente se encuentra en el boleto blanco de 2,2, pero no parece haber ninguna actividad en ella. 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. Por lo que 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 OmniFaces. Tal vez personalmente lo echaré un vistazo.
Un bloque sincronizado retrasar el procesamiento hasta que la solicitud anterior haya terminado. 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.
Utilizando uno de los "nuevos" ámbitos como la conversión de manejar la detección?
Este problema no se puede resolver jugando con ámbitos administrados de beans. Los alcances administrados de beans tienen un propósito diferente: el tiempo de vida de la instancia de beans.
¿Has probado algo como jQuery blockui? Por cierto, el bloque sincronizado no funcionará en un clúster. –
No se ha intentado nada todavía. Esto está en el "bien, ¿cómo hago eso?" escenario. –