使用 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. 验证步骤
-
检查静态资源路径
bashjar -tvf target/*.jar | grep "mdui.min.css" # 正确输出: # BOOT-INF/classes/static/plugins/mdui/css/mdui.min.css
-
访问资源URL
bashcurl -v http://localhost:8080/plugins/mdui/css/mdui.min.css # 预期响应: # HTTP/1.1 200 # Content-Type: text/css
-
查看资源加载日志
在
application.yml
中开启调试日志:yamllogging: level: org.springframework.web: DEBUG
正常日志:
logDEBUG 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
,静态资源处理得以保留,问题自然解决。