【Springboot】解决问题 o.s.web.servlet.PageNotFound : No mapping for *

使用 cursor 进行老项目更新为 springboot 的 web 项目,发生了奇怪的问题,就是 html 文件访问正常,但是静态文件就是 404

检查了各种配置,各种比较,各种调试,最后放弃时候,清理没用的配置文件,发现了一个老的配置类

java 复制代码
@Configuration
public class DateTimeConfig extends WebMvcConfigurationSupport {

    Logger logger = LoggerFactory.getLogger(DateTimeConfig.class);

    @Bean
    public FormattingConversionService mvcConversionService() {
        logger.info("mvcConversionService 执行了");
        DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);

        DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
        dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        dateTimeRegistrar.registerFormatters(conversionService);

        DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
        dateRegistrar.setFormatter(new DateFormatter("yyyy-MM-dd"));
        dateRegistrar.registerFormatters(conversionService);

        return conversionService;
    }
}

WebMvcConfigurationSupport 替换为 WebMvcConfigurerAdapter 解决了问题,原因在于两者在 Spring MVC 中的 行为差异配置优先级。以下是详细分析:


1. 行为差异

特性 WebMvcConfigurationSupport WebMvcConfigurerAdapter
作用 完全覆盖 Spring MVC 默认配置 扩展 Spring MVC 默认配置
影响范围 全局配置,优先级最高 局部配置,优先级较低
推荐使用场景 需要完全自定义 MVC 配置 仅需扩展默认配置

2. 问题根源

使用 WebMvcConfigurationSupport 的问题
  • 覆盖默认配置 :继承 WebMvcConfigurationSupport完全禁用 Spring Boot 的自动配置(如静态资源处理、视图解析器等)。
  • 静态资源失效 :默认的静态资源路径(classpath:/static/)会被覆盖,导致资源无法访问。
使用 WebMvcConfigurerAdapter 的优势
  • 扩展默认配置WebMvcConfigurerAdapter扩展 Spring MVC 配置,不会覆盖默认行为。
  • 保留自动配置:Spring Boot 的自动配置(如静态资源处理)仍然生效。

3. 解决方案

推荐使用 WebMvcConfigurer

WebMvcConfigurerAdapter 已被标记为 @Deprecated,建议直接实现 WebMvcConfigurer 接口:

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
            .addResourceHandler("/plugins/**")
            .addResourceLocations("classpath:/static/plugins/")
            .setCachePeriod(0);
    }
}
关键配置对比
配置项 WebMvcConfigurationSupport WebMvcConfigurer
静态资源处理 需手动配置所有资源路径 仅需扩展默认配置
视图解析器 需手动配置 自动配置 + 扩展
拦截器 需手动注册 自动配置 + 扩展

4. 验证步骤

  1. 检查静态资源路径

    bash 复制代码
    jar -tvf target/*.jar | grep "mdui.min.css"
    # 正确输出:
    # BOOT-INF/classes/static/plugins/mdui/css/mdui.min.css
  2. 访问资源URL

    bash 复制代码
    curl -v http://localhost:8080/plugins/mdui/css/mdui.min.css
    # 预期响应:
    # HTTP/1.1 200
    # Content-Type: text/css
  3. 查看资源加载日志

    application.yml 中开启调试日志:

    yaml 复制代码
    logging:
      level:
        org.springframework.web: DEBUG

    正常日志

    log 复制代码
    DEBUG o.s.w.s.r.ResourceHttpRequestHandler - Resource found: class path resource [static/plugins/mdui/css/mdui.min.css]
  • 优化后的代码

    @Configuration
    public class DateTimeConfig implements WebMvcConfigurer {

    复制代码
      private static final Logger logger = LoggerFactory.getLogger(DateTimeConfig.class);
    
      @Override
      public void addFormatters(FormatterRegistry registry) {
          logger.info("DateTimeConfig: 注册自定义日期时间格式化器");
    
          // 注册 Java 8 日期时间格式化器
          DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
          dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
          dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
          dateTimeRegistrar.registerFormatters(registry);
    
          // 注册传统日期格式化器
          DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
          dateRegistrar.setFormatter(new DateFormatter("yyyy-MM-dd"));
          dateRegistrar.registerFormatters(registry);
      }

    }


5. 总结

  • WebMvcConfigurationSupport :适合需要 完全自定义 MVC 配置的场景,但会 覆盖默认行为
  • WebMvcConfigurer :适合 扩展默认配置,保留 Spring Boot 的自动配置能力。

通过替换为 WebMvcConfigurer,静态资源处理得以保留,问题自然解决。

相关推荐
起这个名字19 小时前
LangGraphJs 核心概念、工作流程理解及应用
前端·人工智能
小赵同学WoW19 小时前
vue组件基础知识
前端
wuyikeer19 小时前
Spring Boot 经典九设计模式全览
java·spring boot·设计模式
牛奶20 小时前
浏览器藏了这么多神器,你居然不知道?
前端·chrome·api
WebInfra20 小时前
Rspack 2.0 正式发布!
前端·javascript·前端框架
极速蜗牛20 小时前
Cursor最近变傻了?
前端
码字小学妹20 小时前
Claude Opus 4.7 接入指南(2026):国内配置 + xhigh 推理 + 成本计算
前端
小赵同学WoW20 小时前
插槽【vue2】与 【vue3】对比
前端
代码随想录20 小时前
Agent大厂面试题汇总:ReAct、Function Calling、MCP、RAG高频问题
前端·react.js·前端框架
前端那点事20 小时前
Vue响应式原理|从底层实现到面试考点,一文吃透(Vue2+Vue3全解析)
前端·vue.js