5

引言

Alice上线后,学生导入模版文件下载失败。

clipboard.png

未打包是没问题的,打完包后就发生了错误。开始逐步定位问题。

原方法

File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "static/导入学生模板.xlsx");
InputStream inputStream = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(inputStream);

经测试,问题出在ResourceUtils.getFile这个方法上。

ResourceUtils.CLASSPATH_URL_PREFIX + "static/导入学生模板.xlsx"

字符串拼接后就是classpath:static/导入学生模板.xlsx,没打包时,该方法能正常获取到该Excel文件。

ResourceUtils.getFile是获取磁盘上的文件,而打完包之后,resources目录了下的所有资源都被打进了jar包,所以不存在相应的Excel文件,获取的时候就报错了。找不到文件。

测试

将打好的jar包解压,主要的东西都在BOOT-INF里。META-INF里面有pom.xml,应该是存储项目信息的。org目录内是springframework的一些class字节码。

clipboard.png

BOOT-INF内就是本项目的核心代码与第三方库。

clipboard.png

classes目录下就是本项目的核心代码,我们的Excel就在这里面。

clipboard.png

lib目录下是项目中引用的第三方jar包,里面有我们常用的slf4jspring-bootjar包。

clipboard.png

所以,Spring Boot的项目一般都较大,有一部分原因是把许多第三方包都打包进去了。

clipboard.png

解决方案

@Autowired一个ResourceLoader,然后调用getResource方法,加载资源。

想想也不难理解,SpringBoot启动时读取application.yml配置,Spring的源码中就是使用ResourceLoader实现的。

只不过源码中直接用的上下文对象,一个上下文对象不只是一个IOC容器,还是一个资源加载器。(上下文其实有很多的功能,可以点开Spring源码看一看,很有意思。)

ResourcePatternResolver派生自ResourceLoader接口。

clipboard.png

clipboard.png

代码模版,以后读取文件就这样写,啥毛病没有:

Resource resource = this.resourceLoader.getResource(ResourceUtils.CLASSPATH_URL_PREFIX + "static/导入学生模板.xlsx");

总结

千淘万漉虽辛苦,吹尽狂沙始到金。
——刘禹锡《浪淘沙词九首·其九》

一路走来,一路总结。最后留下的,是小本本中记录的代码模版与最佳实践。

clipboard.png


张喜硕
2.1k 声望423 粉丝

浅梦辄止,书墨未浓。