2012-02-16 11 views
9

¿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í?Usando JSF 2.0/Facelets, ¿hay alguna manera de conectar un oyente global a todas las llamadas AJAX?

Aquí está el enigma ... Digamos que estás usando etiquetas f: ajax y algo así como apache shiro y dejas que expire tu sesión. 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 manera 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 para escuchar cómo otros han resuelto este problema! Gracias!

+0

Wont [ "ahorro estado inicial al servidor y el estado de transferencia de tiempo de espera de la sesión al cliente para toda la capacidad de respuesta de tiempo"] (http://stackoverflow.com/questions/10378133/initial-state-saving-to-server -on-session-timeout-transfer-to-client-for-all-t) ¿ser una mejor solución para esto en lugar de todas estas cosas traviesas? Me pregunto por qué JSF aún no proporciona esto y si de alguna manera puedo implementar esto. –

Respuesta

16

¿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. A SystemEventListener también. A 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 de JSF, p. dentro de un Filter, luego puede verificar de la siguiente manera si la solicitud actual es o no una solicitud JSF ajax.

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

Aquí está el dilema ... Digamos que usted está utilizando f: ajax etiquetas y algo así como shiro Apache y dejar que la sesión caduca. 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 un redireccionamiento en una solicitud de ajax requiere una respuesta XML especial. Cuando estás dentro del contexto JSF, entonces ExternalContext#redirect() ya lo tiene implícitamente en cuenta. Todo lo que necesita hacer es escribir esto:

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

Si no está dentro del contexto JSF, p. dentro de un Filter, entonces necesitaría escribir usted mismo la respuesta XML completa. P.ej.

response.setContentType("text/xml"); 
response.getWriter() 
    .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") 
    .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", url); 
+0

TSo Supongo que la ruta óptima es escribir un filtro que se encuentra frente al filtro Shiro. Cuando Shiro envíe una redirección, mi filtro la interceptará y enviará el XML. Tengo la sensación de que no puedo hacer esto dentro de la aplicación de rostros porque Shiro bloqueará la solicitud. –

+0

Su mejor apuesta es, de hecho, un filtro en frente del filtro Shiro. – BalusC

+1

Para su información, publiqué en el blog exactamente sobre este caso y proporcioné un filtro completo listo para usar para Shiro: http://balusc.blogspot.com/2013/01/apache-shiro-is-it-ready-for- java-ee-6.html # MakeShiroJSFAjaxAware – BalusC

4

Para redirigir una petición JSF Ajax necesita XML de la siguiente manera

<?xml version="1.0" encoding="UTF-8"?> 
<partial-response> 
     <redirect url="XXX"> 
     </redirect> 
</partial-response> 

Aquí XXX es el URL que desea redirigir a suceder.

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 tener un filtro para toda petición JSF, excepto unos páginas (páginas de inicio de sesión) y comprobar sesión es válida y si es realmente JSF ajax llamada mediante la comprobación de cabecera "Caras-Solicitud", su el valor debe ser "parcial/ajax". Si la sesión ha expirado y es una solicitud ajax, envíe por encima de xml como respuesta.

Debería funcionar.

+0

Wont ["Ahorro de estado inicial al servidor y en el estado de transferencia de tiempo de espera de la sesión al cliente para la capacidad de respuesta de todos los tiempos"] (http://stackoverflow.com/questions/10378133/initial-state-saving-to-server-on-session- timeout-transfer-to-client-for-all-t) ser una mejor solución para esto en lugar de todas estas cosas traviesas? Me pregunto por qué JSF aún no proporciona esto y si de alguna manera puedo implementar esto. –

Cuestiones relacionadas