template springboot page mvc example error custom jsp spring-mvc tomcat servlets custom-error-pages

jsp - springboot - ¿Cómo prioriza el servidor qué tipo de página de error web.xml usar?



spring rest exception handler example (2)

Tengo dos páginas de error; 1 es para SpecificExceptionA y el otro es para Throwable.

<error-page> <exception-type>org.SpecificExceptionA</exception-type> <location>/WEB-INF/views/error/timedout.jsp</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/WEB-INF/views/error/error.jsp</location> </error-page>

Si tengo ambos definidos en mi web.xml, todo va a /error/error.jsp.

Si solo tengo definida la excepción específica, va a la página correcta; pero otros errores van al valor predeterminado de tomcat (excepto 404)

¿Hay una mejor manera de especificar manejadores de excepciones específicos? Estoy usando la primavera 3.0.


Terminé usando Springs SimpleMappingExceptionResolver class

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.*.*.ResponseTimeExceededException"> <!-- the name of the jsp to use for this exception --> error/timedout </prop> </props> </property> <property name="defaultErrorView" value="error/error"/> </bean>


Esto no es específico de Tomcat. Esto es específico de la API de Servlet. La forma en que se determina la página de error se especifica en el capítulo 9.9.2 de la especificación de la API del servlet 2.5 . Aquí hay un extracto de relevancia:

SRV.9.9.2 Páginas de error

Si ninguna declaración de error-page contenga un exception-type ajusta usando la coincidencia de jerarquía de clases, y la excepción lanzada es una ServletException o subclase de la misma, el contenedor extrae la excepción envuelta, como se define en el método ServletException.getRootCause . Se realiza una segunda pasada sobre las declaraciones de la página de error, intentando nuevamente la coincidencia con las declaraciones de la página de error, pero utilizando la excepción envuelta.

Por lo tanto, es probable que su SpecificExceptionA esté envuelta en ServletException y, por lo tanto, java.lang.Throwable es la coincidencia más cercana en 1st pase. Cuando elimine esta entrada, se realizará un segundo pase con la excepción envuelta y, por lo tanto, su SpecificExceptionA obtendrá una coincidencia.

La forma correcta de definir una página de error HTTP 500 general es asignarla en el error-code lugar del exception-type de exception-type :

<error-page> <exception-type>org.SpecificExceptionA</exception-type> <location>/WEB-INF/views/error/timedout.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/views/error/error.jsp</location> </error-page>

Si esto no es una opción por algún motivo poco claro, una de las formas de solución es crear un Filter que escuche en un url-pattern de url-pattern de /* y básicamente haga lo siguiente:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { try { chain.doFilter(request, response); } catch (ServletException e) { Throwable rootCause = e.getRootCause(); if (rootCause instanceof SpecificExceptionA) { throw (SpecificExceptionA) rootCause; } else { throw e; } } }

Solo tiene que extenderse desde RuntimeException para que funcione.