【问题标题】:web.xml error-page location redirect is not going through my filter definitionsweb.xml 错误页面位置重定向未通过我的过滤器定义
【发布时间】:2012-02-25 18:16:03
【问题描述】:

在我的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 的 handler not found 条件。我的应用程序是一个多租户应用程序,其中一些过滤器负责设置与架构相关的一些信息。

请求到达我的error.vm 控制器,但由于它们正在通过过滤器,我无法确定themeSecurityContext 等。

如何解决这个问题?

谢谢。

【问题讨论】:

    标签: spring-mvc error-handling web.xml


    【解决方案1】:

    也许

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2015-03-17
        • 2013-11-01
        • 2012-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多