jsp / spring-mvc исключение при рендеринге - как получить пользовательскую страницу ошибки и записать исключение - PullRequest
5 голосов
/ 21 сентября 2011

Если исключение происходит в сервисе или контроллере, оно обрабатывается Springler HandlerExceptionResolvers.Однако, если в обработке .jsp есть исключение (например - PropertyNotFoundException, происходит даже с JSTL), то Spring не пропустит это через механизм обработки исключений.Более того, это не считается ошибкой 500, поэтому конфигурация <error-page> не учитывается

Вместо этого исключение распространяется на контейнер сервлета.Это нормально, но на самом деле я не могу получить желаемое поведение:

  • показать страницу ошибки (500)
  • записать исключение

Моя текущая настройка:

  • 500.jsp имеет isErrorPage=true
  • все jsps включают в себя общий файл, который имеет <%@ page errorPage="500.jsp" %>

Что происходитесть - исключение нигде не записано.И страница ошибки не отображается.Вместо этого запрошенная страница отображается наполовину отрендеренной.Если я увеличу размер буфера (достаточно, чтобы добраться до проблемного фрагмента кода), только тогда отобразится страница с ошибкой.(опять же, без регистрации)

Итак, как мне добиться того, чего я хочу?Без изменения размера буфера, без использования <c:catch> и без ex.printStackTrace() на странице ошибок)

Ответы [ 3 ]

2 голосов
/ 21 сентября 2011

Добавьте это в web.xml:

<servlet>
  <servlet-name>ErrorServlet</servlet-name>
  <servlet-class>package.of.ErrorServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>ErrorServlet</servlet-name>
  <url-pattern>/WEB-INF/servlets/error</url-pattern>
</servlet-mapping>

<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/WEB-INF/servlets/error</location>
</error-page>

В методе ErrorServlet реализуется метод doService, поскольку контейнер сервлета будет перенаправлять туда все текущие действия (GET, POST и т. Д.).

Добавить этот вспомогательный метод

    public static < T extends Throwable > T getExceptionFromRequest (
            final Class< T > exception_class,
            final HttpServletRequest request                
        )
    {
        final T ret_val =
            exception_class.cast(
                request.getAttribute( SERVLET_EXCEPTION_ATTR )
            );

        if ( ret_val != null )
        {
            return ret_val;
        }

        return
            exception_class.cast(
                request.getAttribute( JSP_EXCEPTION_ATTR )
            );
    }

И эти 2 константы:

    public final static String SERVLET_EXCEPTION_ATTR =
        "javax.servlet.error.exception";

    public final static String JSP_EXCEPTION_ATTR =
        "javax.servlet.jsp.jspException";

Это работает для меня в Tomcat.

1 голос
/ 21 сентября 2011

Можете ли вы использовать HandlerInterceptor с пустыми preHandle() и postHandle(), но обслуживающими исключения в afterComplete()?

0 голосов
/ 21 сентября 2011

Похоже, есть 2 вопроса:

  1. Вы можете установить размер буфера прямо в вашем JSP, чтобы избежать полусъемки; поскольку вы уже устанавливаете isErrorPage, это будет соответствовать вашему текущему дизайну
  2. Вы можете записать ошибку со страницы 500, согласно этому примеру
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...