SpringBoot项目打包成jar后,使用ClassPathResource获取classpath(resource)下文件失败_jar classpathresource-程序员宅基地

技术标签: spring boot  classpath  resource  无法读取资源文件  jar  

我在读取邮件模板的时候,本地测试使用ClassPathResource都可以正常读取,但打包成jar包传到服务器上就无法获取了,报错信息是:class path resource [xxxx] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:xxxx.jar!/BOOT-INF/classes!xxxx,话不多说,先看正确的获取方法:使用PathMatchingResourcePatternResolver。

String txt = "";
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("templates/layout/email.html");
Resource resource = resources[0];
//获得文件流,因为在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流
InputStream stream = resource.getInputStream();
StringBuilder buffer = new StringBuilder();
byte[] bytes = new byte[1024];
try {
    for (int n; (n = stream.read(bytes)) != -1; ) {
        buffer.append(new String(bytes, 0, n));
    }
} catch (IOException e) {
    e.printStackTrace();
}
txt = buffer.toString();

然后,想知道更多的咱们就继续看看是怎么回事,如果只是为了解决问题,那就可以忽略下面的内容了。

为了老夫好奇的心,我们继续探索下去,到底是怎么回事?我们先看看之前的代码:

String txt = "";
Resource resource = new ClassPathResource("templates/layout/email.html");
txt = fileUtil.readfile(resource.getFile().getPath());

其实这是一个jar包发布的大坑,相信很多小伙伴遇到了读取文件的问题,其实使用getFile()的时候的坑,为了弄明白到底是咋回事,我进行了跟踪,结果返回的是一个Jar协议地址:jar:file:/xxx/xx.jar!/xxxx。
 

然后继续跟踪到org.springframework.util.ResourceUtils#getFile(java.net.URL, java.lang.String)中,有如下的判断:

public static File getFile(URL resourceUrl, String description) throws FileNotFoundException {
    Assert.notNull(resourceUrl, "Resource URL must not be null");
    if (!"file".equals(resourceUrl.getProtocol())) {
        throw new FileNotFoundException(description + " cannot be resolved to absolute file path because it does not reside in the file system: " + resourceUrl);
    } else {
        try {
            return new File(toURI(resourceUrl).getSchemeSpecificPart());
        } catch (URISyntaxException var3) {
            return new File(resourceUrl.getFile());
        }
    }
}

因为resourceUrl.getProtocol()不是file,而是 jar,这样就抛出了一个FileNotFoundException异常。

ResouceUtils.getFile()是专门用来加载非压缩和Jar包文件类型的资源,所以它根本不会去尝试加载Jar中的文件,要想加载Jar中的文件,只要用可以读取jar中文件的方式加载即可,比如 xx.class.getClassLoader().getResouceAsStream()这种以流的形式读取文件的方式,所以使用读取文件流就可以拿到了。

解决方案一:在jar包中使用文件流读取。

ExcelWriter excelWriter = EasyExcel.write(httpResponse.getOutputStream())
                .withTemplate(new ClassPathResource("templates/excel/b2cSaleOrder/OrderListExportTemplate.xlsx").getInputStream())
                .build();
            WriteSheet writeSheetOne = EasyExcel.writerSheet("Sheet1").build();
            excelWriter.fill(listOne, writeSheetOne);
            excelWriter.finish();

解决方案二:通过指定类所在的目录来指定模板所在根路径

String fontPath = new ClassPathResource("/fonts/", FontUtil.class.getClassLoader()).getFile().getPath();
或
String templatePath = new ClassPathResource("/templates/excel/b2cSaleOrder/OrderListExportTemplate.xlsx", FontUtil.class.getClassLoader()).getFile().getPath();

参考文章1:SpringBoot项目打包成jar后读取文件的大坑,使用ClassPathResource获取classpath下文件失败 - Posts - 任霏的博客

参考文章2:打包成jar后读取文件的大坑:使用ClassPathResource获取classpath下文件失败_赶路人儿的博客-程序员宅基地 

参考文章3:freemaker模板位置ClassTemplateLoader的绝对路径相对路径设置方法_机械手学Java的博客-程序员宅基地_freemarker 模板路径

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lisheng19870305/article/details/124112118

智能推荐

Kubernetes为什么叫K8S,K8S的优势到底是什么让它成为当前热门?_kubernetes的优势有哪些-程序员宅基地

文章浏览阅读3.5k次。Kubernetes简介、优势、架构优势、用途、核心概念、术语、快速部署_kubernetes的优势有哪些

DO-178B及DO-178C中的MC/DC有什么不同?-程序员宅基地

文章浏览阅读705次。本文简要讨论了DO-178B及DO-178C中MC/DC的定义。简而言之,DO-178B仅允许唯一原因MC/DC,DO-178C扩展了屏蔽MC/DC及短路MC/DC,大大增强了对存在耦合条件情况的适用性。_do-178c

【PTA】【浙大版《Python 程序设计》7-4 特殊a串数列求和 (20 分)_pta7-4求累加和-程序员宅基地

文章浏览阅读1.1k次。给定两个均不超过9的正整数a和n,要求编写程序求a+aa+aaa++⋯+aa⋯a(n个a)之和。输入格式:输入在一行中给出不超过9的正整数a和n。输出格式:在一行中按照“s = 对应的和”的格式输出。输入样例:2 3输出样例:s = 246思路:列表解析式构建列表,再求和a,n=list(map(int, input().split())) s = sum([int(s..._pta7-4求累加和

AttributeError: module ‘torch.distributed‘ has no attribute ‘deprecated‘的问题解决_module 'torch.distributed' has no attribute 'reduc-程序员宅基地

文章浏览阅读2.8k次,点赞2次,收藏2次。Traceback (most recent call last): File "<stdin>", line 1, in <module> File "D:\metya\Anaconda3\lib\site-packages\apex\__init__.py", line 4, in <module> from . import parallel File "D:\metya\Anaconda3\lib\site-packages\apex\par._module 'torch.distributed' has no attribute 'reduceop

oracle之索引优化_oracle索引的使用和优化-程序员宅基地

文章浏览阅读2.4k次。oracle中单列索引和复合索引的选择以及导致索引失效一些常见情况(包含对最佳左前缀和全表扫描的描述)_oracle索引的使用和优化

15.脚本备份、恢复达梦DM数据库_docker 达梦数据库 备份恢复-程序员宅基地

文章浏览阅读458次,点赞8次,收藏11次。脚本命令恢复、备份达梦DM数据库_docker 达梦数据库 备份恢复

随便推点

请问想考软考,零基础的话,哪个证书最好考呢_软考哪个容易通过-程序员宅基地

文章浏览阅读4k次。网络工程师、多媒体应用设计师、嵌入式系统设计师、计算机辅助设计师、电子商务设计师、信息系统监理师、数据库系统工程师、系统集成项目管理工程师、信息系统管理工程师、信息安全工程师、计算机硬件工程师、信息技术支持工程师、软件评测师、软件设计师、软件过程能力评估师。记住十大知识领域的各个过程输入输出,另一个重要原因就是,不管考试考哪一个过程,你只要记住了那个过程的流程,在读案例的时候就根据标准的流程去检查,这样能准确的知道案例的问题在哪里。(1)熟悉信息化知识和信息化技术,了解我国信息化建设的有关政策和发展规划;_软考哪个容易通过

Android Studio运行遇到 Error while Launching activity问题_androidstudio运行一直显示在lanching app-程序员宅基地

文章浏览阅读1w次,点赞5次,收藏2次。当我们写完应用程序,先测试一下,其他的什么都没有做的时候,发现怎么都运行不了,而且还出现 Error while Launching activity这个错误,其实这个错误非常好解决,只需要在build中选择clean就可以。是不是很神奇呢!本人菜鸟一个,有什么不对的地方希望大家指出评论,大神勿喷,希望大家一起学习进步!_androidstudio运行一直显示在lanching app

华为nova7se乐活版支持鸿蒙,华为nova7se乐活版和nova8se的详细对比参数对比-程序员宅基地

文章浏览阅读1.3k次。原标题:华为nova7se乐活版和nova8se的详细对比参数对比华为nova7se乐活版和nova8se作为性价比还不错的中端机型,不少小伙伴们不知道该如何选择?那么华为nova7se乐活版和nova8se相比哪款更值得大家入手?小编为大家带来关于华为nova7se乐活版和nova8se的详细对比,欢迎查看。1、主要参数对比参数配置华为nova7SE乐活版华为nova8SE屏幕尺寸6.5英寸6...._华为nova7se可以正常使用华为钱包

Android 录音功能直接拿去用-程序员宅基地

文章浏览阅读95次。前言最近项目中需要用到录音的功能,借鉴了外国一位哥们的项目github.com/dkim0419/So…,搞定需求之后,花了些时间封装成一个录音的工具包,分享给大家,需要源码的 点击这里先贴个效果图给大家看一下,看看这个录音包的功能一、实现录音的 Service这个类可以说是这个包的核心了,如果理解了这个 Service,录音这一块基本就没什么问题了。录音主要是利用 MediaRecod..._mrecorder.setaudioencodingbitrate

【毕业设计/课程设计】基于SSM的二手交易商城的设计与实现(源码+文章) Java | JSP | MVC | Web_二手商城毕设-程序员宅基地

文章浏览阅读229次。系统采用Java语言开发,数据库使用MySql,后端框架采用SSM系统一共分为3个角色,分别是游客、会员、系统管理员。游客端功能:注册、二手商品信息搜索、二手商品信息浏览、求购信息浏览、评论信息浏览。管理员端功能:登录、二手商品审核、二手商品类型管理、用户管理。_二手商城毕设

一位大牛整理的Python 资源_pqr插件 wow-程序员宅基地

文章浏览阅读470次。原文地址:一位大牛整理的Python 资源 作者:helloworld0820zz:一位大牛整理的Python资源(2009-10-10 13:12:40)标签:杂谈 分类:Python来自http://blog.sina.com.cn/s/blog_5d236e060100ep4y.html~type=v5_one&label=rela_n_pqr插件 wow