Spring Boot 2.6同时实现404异常处理与静态资源映射的方案咨询
问题根源
你原有配置关闭了全部静态资源映射(spring.web.resources.add-mappings: false),才能让所有无匹配Handler的请求抛出NoHandlerFoundException走自定义404处理。引入altair依赖后,其静态资源依赖Spring默认的静态资源映射能力,关闭映射后自然无法访问。如果开启映射,Spring默认会对所有路径先匹配静态资源,匹配失败后不会抛出异常,直接走默认错误页,导致原有404处理失效。
实现方案
方式1:仅通过yaml配置(可满足大部分场景)
仅需调整静态资源匹配路径规则,让只有altair相关前缀的请求才会进入静态资源匹配流程,其他路径仍保持原有逻辑,无匹配Handler时抛出异常:
spring: mvc: throw-exception-if-no-handler-found: true # 仅匹配altair静态资源路径,如有自有静态资源可追加,用逗号分隔,比如/static/**,/vendor/altair/** static-path-pattern: /vendor/altair/** web: resources: add-mappings: true # 保留默认静态资源查找位置,altair静态资源默认存放在META-INF/resources下,无需修改 static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
该方式的唯一限制:如果用户访问不存在的altair静态资源,会返回Spring默认白页404,不会走你自定义的404处理,如果需要覆盖该场景,需要增加少量代码配置。
方式2:yaml+少量代码(全场景覆盖)
首先使用上面的yaml配置,再新增如下配置类,将所有404状态码都转发到自定义的错误处理接口:
import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; @Configuration public class CustomErrorConfig { @Bean public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> errorPageCustomizer() { return factory -> factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/custom/404")); } }
再新增对应错误处理接口,返回你需要的404响应格式即可:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class CustomErrorController { @GetMapping("/custom/404") public String handle404() { // 自定义返回逻辑 return "请求的资源不存在"; } }
该方式可以覆盖所有404场景,包括接口不存在、静态资源不存在的情况。
常见疑问解答
- 仅通过application.yaml是否可以实现全场景需求?
不能。如果不需要处理静态资源不存在的404场景,仅用yaml即可实现;如果需要覆盖所有404场景,必须增加少量代码配置。
内容的提问来源于stack exchange,提问作者Dilermando Lima
相关产品推荐
相关产品推荐

