SpringBoot项目,jar包获取不到resources下文件

2,808 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-Debug实录任务,点击查看活动详情

背景

SpringBoot项目中使用 poi-tl 导出 word文件,在模板的基础上,填充相关数据,生成给用户使用。

报错

模板导出在本地测试时,接口正常;但在打包发布线上测试时,报错找不到文件:

Cannot find the find [src/main/resources/template/template.docx]

具体代码:

String template = "src/main/resources/template/template.docx";
String output = "src/main/resources/output.docx";
XWPFTemplate template = XWPFTemplate.compile(template).render(personInfoDTO);
try {
    template.writeAndClose(new FileOutputStream(output));
} catch (IOException e) {
    log.error("IOException生成文件报错", e);
    failResult.setMsg(e.toString());
    return failResult;
}

问题分析

  1. 报错提示是没有找到文件,怎么可能没有文件呢?本地就可以到处额,回头一想,线上是jar包发布,没法直接访问到jar包中的文件,那就导致了接口报错!
  2. 查了网上相关资料后,可通过 ClassPathResourcegetResourceAsStream的方式读取到 jar包中的文件。

解决方案

// ClassPathResource 方式
InputStream templateInputStream = null;
try {
    // 打包后,需要从流中获取文件模板
    templateInputStream = new ClassPathResource("template/template.docx").getInputStream();
} catch (IOException e) {
    log.error("模板IOException", e);
    failResult.setMsg(e.toString());
    return failResult;
}

// getResourceAsStream 方式
InputStream templateInputStream = Thread.currentThread().getContextClassLoader() 
.getResourceAsStream("template/template.docx");

小插曲

在确定使用 ClassPathResource 的方式获取 jar包中的文件后,省事直接调用了 .getFile() 方法:

InputStream templateInputStream = new ClassPathResource("template/judge_template.docx").getFile();

然后就报错:

"java.io.FileNotFoundException: class path resource [template/template.docx] cannot be resolved to absolute file path
because it does not reside in the file system: jar:file:/server/xxx/lib/xxx.jar!/BOOT-INF/classes!/template/template.docx"

注意获取流,而不是获取文件。

参考

1、SpringBoot项目打包成jar后获取classpath下文件失败
2、此文要从SpringBoot打包后不能读取classpath下文件说起