Переадресация на страницу ошибки web.xml не проходит через мои определения фильтров - PullRequest
2 голосов
/ 03 февраля 2012

В моем web.xml я сделал следующие error-page отображения, но когда они вызываются, эти вызванные запросы не проходят через определения фильтра, указанные в web.xml файле.

<error-page>
    <error-code>403</error-code>
    <location>/error.vm?id=403</location>
</error-page>

<error-page>
    <error-code>400</error-code>
    <location>/error.vm?id=400</location>
</error-page>

<error-page>
    <error-code>404</error-code>
    <location>/error.vm?id=404</location>
</error-page>

<error-page>
    <exception-type>javax.servlet.ServletException</exception-type>
    <location>/servlet-exception.vm</location>
</error-page>

Мое приложение использует spring-mvc, и я хочу обработать условие handler not found от spring mvc. Мое приложение является мультитенантным приложением, в котором некоторые фильтры отвечают за установку некоторой информации, связанной со схемой.

Запросы поступают в мой контроллер error.vm, но, поскольку они проходят через фильтр, я не могу определить theme и SecurityContext и т. Д.

Как решить эту проблему?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 08 февраля 2012

Вместо использования страниц ошибок web.xml вы можете использовать фильтр сервлетов.Фильтр сервлета может использоваться для перехвата всех исключений или только определенного исключения, такого как org.springframework.web.portlet.NoHandlerFoundException.(Это то, что вы подразумеваете под исключением «обработчик не найден»?)

Фильтр будет выглядеть примерно так:

package com.example;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.springframework.web.portlet.NoHandlerFoundException;

public class ErrorHandlingFilter implements Filter {

    public void init(FilterConfig config) throws ServletException { }

    public void destroy() { }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        try {
            chain.doFilter(request, response);
        } catch (NoHandlerFoundException e) {
            // Or you could catch Exception, Error, Throwable...

            // You probably want to add exception logging code here.

            // Putting the exception into request scope so it can be used by the error handling page    
            request.setAttribute("exception", e);

            // You probably want to add exception logging code here.
            request.getRequestDispatcher("/WEB-INF/view/servlet-exception.vm").forward(request, response);
        }
    }
}

Затем настройте это в web.xml с помощьюSpring's DelegatingFilterProxy:

<filter>
    <filter-name>errorHandlingFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>errorHandlingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

И, наконец, превратите фильтр в пружинный компонент внутри контекста Spring. xml:

<bean id="errorHandlingFilter" class="com.example.ErrorHandlingFilter" />

Возможно, вам придется поэкспериментировать с порядком фильтра.в цепочке фильтров, чтобы неудавшиеся запросы все равно проходили через другие фильтры, которые вы упомянули.Если у вас возникли проблемы с этим, можно было бы сделать перенаправление HTTP вместо переадресации, например:

   try {
        chain.doFilter(request, response);
    } catch (NoHandlerFoundException e) {
            request.getSession().setAttribute("exception", e);
            response.sendRedirect("/servlet-exception.vm");
    }

Это заставило бы браузер запросить страницу обработки ошибок в качестве нового httpзапрос, который может упростить гарантию, что сначала он проходит через все нужные фильтры.Если вам нужен исходный объект исключения, то вы можете поместить его в сеанс вместо запроса.

2 голосов
/ 31 августа 2013

возможно

<filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>ERROR</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>
...