SpringBoot项目获取静态资源文件报错解决方案
问题描述
在SpringBoot项目部署到生产环境后,尝试读取jar包中的静态资源文件时遇到如下错误:
class path resource [monthReport.xls] cannot be resolved to absolute file path
because it does not reside in the file system:
jar:nested:/xxx/project.jar/!BOOT-INF/lib/project-1.0.0-SNAPSHOT.jar!/monthReport.xls
问题原因
- SpringBoot项目使用
spring-boot-maven-plugin插件打包时,会将所有资源文件打包到jar包内部 - 在jar包运行环境中,无法直接通过文件系统路径访问jar内部的资源文件
- 需要使用专门的资源加载方式来读取jar包中的文件
解决方案
针对这个问题,主要有两种解决方案:
方案一:将资源文件放在外部目录
- 将静态资源文件放在项目的
resources/static目录下 - 或通过
application.properties配置外部资源目录:
spring.resources.static-locations=file:/path/to/your/static/files
方案二:使用ResourceLoader加载(推荐)
使用Spring提供的ResourceLoader来正确加载jar包中的资源文件:
@Autowired
private ResourceLoader resourceLoader;
public void loadFile(String filePath) {
// 使用classpath路径加载资源
Resource resource = resourceLoader.getResource("classpath:" + filePath);
// 获取输入流读取文件内容
try (InputStream inputStream = resource.getInputStream()) {
// 进行文件处理...
} catch (IOException e) {
// 异常处理
}
}
注意:在jar包环境中,请使用
resource.getInputStream()而不是resource.getFile(),
因为getFile()方法在jar包环境中会抛出异常。
最佳实践建议
- 对于需要频繁更新的文件,建议使用方案一,将文件放在外部目录
- 对于应用内置的静态文件,建议使用方案二,通过ResourceLoader加载
- 在开发环境和生产环境都建议使用统一的资源访问方式,避免环境差异导致的问题