spring-mvc - web.xml 错误页面位置重定向未经过我的过滤器定义

标签 spring-mvc error-handling web.xml

在我的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,我想处理 spring mvc 中的未找到处理程序情况。我的应用程序是一个 Multi-Tenancy 应用程序,其中一些过滤器负责设置与架构相关的一些信息。

请求已到达我的 error.vm Controller ,但由于它们通过过滤器传递,我无法确定 主题SecurityContext 等等

如何解决这个问题?

谢谢。

最佳答案

您可以使用 servlet 过滤器,而不是使用 web.xml 的错误页面。 servlet 过滤器可用于捕获所有异常,或仅捕获特定异常,例如 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);
        }
    }
}

然后,借助 Spring 的 DelegatingFilterProxy 在 web.xml 中进行设置:

<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 中的 spring bean:

<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 请求进行请求,这可能会更容易确保它首先通过所有正确的过滤器。如果您需要原始异常对象,那么您可以将其放在 session 中而不是请求中。

关于spring-mvc - web.xml 错误页面位置重定向未经过我的过滤器定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9123403/

相关文章:

java - Spring3 与 Tapestry 5.3

Spring Security + JPA 用户架构

java - 我不断收到<identifier>预期错误

spring-mvc - 停用 Jetty 的默认 404 错误处理程序

java - 如何在spring-mvc中接受具有相同id的多个REST查询参数?

java - 在多模块 Spring Boot 项目中使用属性

Apache 错误与 throws 类不兼容

Java 等同于未捕获异常的 coredump

JBoss AS 7中web.xml中没有角色的身份验证

java - 对 JBoss web.xml 的更改无效