jsf servlets web.xml custom-error-pages viewexpiredexception

jsf - ViewExpiredException se muestra en java.lang.Throwable error-page en web.xml



servlets custom-error-pages (1)

Esto se debe a que la ViewExpiredException se envuelve en una ServletException según la especificación JSF. Aquí hay un extracto del capítulo 10.2.6.2 de la especificación JSF 1.2 :

10.2.6.2 FacesServlet

Llame al método execute() de la instancia de Lifecycle guardada, pasando la instancia de FacesContext para esta solicitud como un parámetro. Si el método execute() lanza una FacesException , vuelva a lanzarlo como una ServletException con la FacesException como la causa raíz .

La forma en que se asignan las páginas de error se especifica en la especificación de la API de Servlet. Aquí hay un extracto del capítulo 9.9.2 de la especificación 2.5 de la API de Servlet :

SRV.9.9.2 páginas de error

Si no hay error-page declaración de error-page contenga un exception-type ajuste a la coincidencia de jerarquía de clases , y la excepción lanzada sea una excepción ServletException o subclase de la misma, el contenedor extrae la excepción envuelta, según lo define el método ServletException.getRootCause . Se realiza una segunda pasada sobre las declaraciones de la página de error, intentando de nuevo la coincidencia con las declaraciones de la página de error, pero en su lugar utiliza la excepción envuelta.

En la jerarquía de clases, la ServletException ya coincide con Throwable , por lo que su causa raíz no se extraerá para el segundo paso.

Para probar este comportamiento especificado, reemplace javax.faces.application.ViewExpiredException por javax.servlet.ServletException como <exception-type> y vuelva a intentarlo. Verás la página de error esperada que se muestra.

Para resolver esto, simplemente elimine la página de error en java.lang.Throwable o java.lang.Exception . Si ninguna página de error específica de una excepción coincide, entonces, de todos modos, volverá al código de error de 500 . Entonces, todo lo que necesitas es esto:

<error-page> <exception-type>javax.faces.application.ViewExpiredException</exception-type> <location>/jsps/utility/sessionExpired.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/jsps/utility/technicalError.jsp</location> </error-page>

Actualización : según el comentario (eliminado) del OP: para probar esto de manera confiable, no puede throw new ViewExpiredException() una throw new ViewExpiredException() en un constructor o método de bean, o algo así. A su vez, sería envuelto en alguna excepción EL. Eventualmente, puede agregar una línea de depuración imprimiendo rootCause en el Filter para verlo usted mismo.

Si está utilizando Eclipse / Tomcat, una manera rápida de probar la ViewExpiredException es la siguiente:

  1. Cree una página JSF con un simple botón de comando, desplácelo, ejecútelo y ábralo en el navegador web.
  2. Vuelva a Eclipse, haga clic derecho en el servidor Tomcat y elija Limpiar el Directorio de trabajo de Tomcat . Esto reiniciará Tomcat y trash todas las sesiones serializadas (¡importante! Simplemente reiniciar Tomcat no es suficiente).
  3. Vuelva al navegador web y presione el botón de comando (¡sin volver a cargar la página de antemano!).

Estoy trabajando en una aplicación web JSF en la que necesito mostrar una página "Session Expired" si la vista caduca, pero una página de error técnico general para todos los demás. La aplicación solo va a la página de error técnico cuando desencadeno la excepción. Aquí están las definiciones de la página de error:

<error-page> <exception-type>javax.faces.application.ViewExpiredException</exception-type> <location>/jsps/utility/sessionExpired.jsp</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/jsps/utility/technicalError.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/jsps/utility/technicalError.jsp</location> </error-page>

Eliminé los elementos de la página de error technicalError.jsp y funcionó bien, pero cuando los vuelvo a colocar no puedo acceder a la página sessionExpired.jsp. ¿Cómo le digo al contenedor web el orden para evaluar estas etiquetas para que aparezca la página correcta? Gracias.