Usando JSF 2.0 / Facelets, ¿hay alguna manera de conectar un oyente global a todas las llamadas AJAX?

¿Hay alguna manera de conectar un oyente global a todas las llamadas AJAX en JSF? ¿Quizás a través de un oyente de fase o algo así?

Aquí está el enigma … Digamos que estás usando tags f: ajax y algo así como apache shiro y dejas que tu sesión expire. Luego vuelves y haces clic en un botón que tiene un f: ajax adjunto. El servidor responderá con un redireccionamiento 302 a la página de inicio de sesión.

El usuario no ve nada Pueden hacer clic repetidamente e invocar la llamada ajax, pero para ellos la aplicación simplemente está “muerta”.

Así que, aunque creo, ¿hay alguna forma de conectar un oyente a todas las llamadas ajax en JSF? Si es así, lo que me gustaría hacer es monitorear el código de respuesta. Si se trata de una redirección, use window.navigate para enviarlos a lo largo de su camino.

¡Siempre estoy abierto a escuchar cómo otros han resuelto este problema!

¿Hay alguna manera de conectar un oyente global a todas las llamadas AJAX en JSF? ¿Quizás a través de un oyente de fase o algo así?

Sí, un PhaseListener puede hacerlo. Un SystemEventListener también. Un Filter también.

Si se encuentra dentro del contexto de JSF, puede verificar de la siguiente manera si la solicitud actual es una solicitud de AJAX o no.

 if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) { // It's an ajax request. } 

Si no está dentro del contexto JSF, por ejemplo, dentro de un Filter , puede verificar de la siguiente manera si la solicitud actual es o no una solicitud JJA Ajax.

 if ("partial/ajax".equals(request.getHeader("Faces-Request"))) { // It's a JSF ajax request. } 

Aquí está el enigma … Digamos que estás usando tags f: ajax y algo así como apache shiro y dejas que tu sesión expire. Luego vuelves y haces clic en un botón que tiene un f: ajax adjunto. El servidor responderá con un redireccionamiento 302 a la página de inicio de sesión.

El usuario no ve nada Pueden hacer clic repetidamente e invocar la llamada ajax, pero para ellos la aplicación simplemente está “muerta”.

Forzar una redirección en una solicitud de ajax requiere una respuesta XML especial. Cuando estás dentro del contexto JSF, ExternalContext#redirect() ya lo tiene implícitamente en cuenta. Todo lo que necesitas hacer es escribir esto:

 FacesContext.getCurrentInstance().getExternalContext().redirect(url); 

Si no estás dentro del contexto JSF, por ejemplo, dentro de un Filter , entonces necesitarás escribir la respuesta XML completa por ti mismo. P.ej

 response.setContentType("text/xml"); response.getWriter() .append("") .printf("", url); 

Para redirigir una solicitud jsf ajax necesita xml de la siguiente manera

      

Aquí XXX es la URL que desea que se redireccione.

En ajax la redirección de llamada enviada no es como la anterior, por lo tanto, no hay redirección.

Para obtener el resultado deseado, tenga un filtro para todas las solicitudes jsf excepto algunas páginas (página de inicio de sesión) y la sesión de verificación sea válida y si es realmente jsf ajax llame revisando el encabezado “Faces-Request”, su valor debe ser “partial / ajax” . Si la sesión ha expirado y es una solicitud ajax, envíe xml como respuesta.

Deberia de funcionar.