如何在 spring-boot 中拦截嵌入式 Tomcat 上的“全局”404

Posted

技术标签:

【中文标题】如何在 spring-boot 中拦截嵌入式 Tomcat 上的“全局”404【英文标题】:How to intercept "global" 404s on embedded Tomcats in spring-boot 【发布时间】:2015-10-25 00:41:57 【问题描述】:

我对 spring-boot 附带的嵌入式 tomcat 有一个相当奇怪的问题,特别是它的错误处理。

基本上,我正在尝试通过自定义处理程序处理所有异常。 长话短说:它适用于除 404 之外的所有内容。是否通过任何其他机制而不是异常处理?

我测试的所有其他状态代码都调用了我的自定义解析器,只有 404 为我提供了默认的 Tomcat 404 页面。更具体地说,404 被抛出控制器之外,例如如果只有 /test 注册的控制器,则请求 /teXst。在这种异常情况下,我不会调用我的解析器,只会看到默认的 Tomcat HTTP 状态 404 页面。

知道什么会妨碍我吗? 这是我设置解析器的方法

public class GlobalExceptionResolver extends AbstractHandlerExceptionResolver 
        @Override
        public int getOrder() 
            return Integer.MIN_VALUE;
        

        @Override
        protected boolean shouldApplyTo(HttpServletRequest request, Object handler) 
            return true;
        

        @Override
        protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 
     // my stuff ending with returning an instance of ModelAndView
    

为了让所有默认的 Spring-Boot 错误处理不受我注释的影响

@EnableAutoConfiguration(exclude = org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration.class)

这给我留下了 404、500 等的默认 Tomcat 错误页面,最后设置了我的自定义处理程序

@Bean
public WebMvcConfigurerAdapter adapter() 
    return new WebMvcConfigurerAdapter() 
        @Override
        public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) 
            exceptionResolvers.add(new GlobalExceptionResolver());
        

如上所述,此设置适用于除 HTTP 状态 404 之外的所有异常。知道什么机制创建这些页面以及为什么不调用我的异常解析器吗?这是在 Spring Boot 1.2.5.RELEASE 上使用 Spring MVC 4.1.7.RELEASE 和嵌入式 Tomcat 8.0.23

【问题讨论】:

【参考方案1】:

事实证明,我找到了答案。这是不可能通过 Spring Configuration 实现的,但您可以创建自己的 ServletDispatcher 并将其配置为抛出异常,如下所述:How to configure default DispatcherServlet?

那么我上面的代码可以很好地捕获 404

【讨论】:

以上是关于如何在 spring-boot 中拦截嵌入式 Tomcat 上的“全局”404的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot 拦截器不拦截

spring-boot整合SSM框架

如何禁用嵌入式数据库 Spring-boot spring-data-jpa

如何使用带有 gradle 的多个嵌入式服务器运行 spring-boot 集成测试

当两个应用程序都使用嵌入式activemq时,如何将Jms消息从一个spring-boot应用程序发送到另一个应用程序

spring-boot添加自定义拦截器