SpringBoot项目打包成jar后读取文件的大坑,使用ClassPathResource获取classpath下文件失败
我在读取邮件模板的时候,本地测试使用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()这种以流的形式读取文件的方式,所以使用读取文件流就可以拿到了。
商业用途请联系作者获得授权。
版权声明:本文为博主「任霏」原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接及本声明。
相关推荐
猜你还喜欢这些内容,不妨试试阅读一下评论与留言
以下内容均由网友提交发布,版权与真实性无法查证,请自行辨别。- 2020-09-12 22:49:35
- Wuxi, Jiangsu, China
- 回复
微信订阅号
扫码关注「任霏博客」微信订阅号- 你好,我想问一下如果是分析型的数据库要怎么制作docker镜像呢 是修改V008R003C002B0320版本号吗
- 可以的,我也正在开发分享的程序,可以邮件或群联系我都可以,关于页面里有联系方式:https://www.renfei.net/page/about 。
- 有破解软件的需要可以私下联系您吗?
- 您好,手机APP只是个客户端,用于数据呈现展示,数据均保存在服务器上,只留个APP没有任何用处,无能为力哦。
- 老哥 看你弄了这么多软件好厉害啊。 我有个软件 我买过几个小会员 没用几天 然后商家跑路了,软件服务器关闭了,连不上去 用不了。 你能做成一个打补丁版本可以本地用的么? 方便看下么?https://haodezhe.lanzouw.com/iD0f30h9joza 谢谢老哥!
- 您好,由于版权投诉和我国知识产权法的完善,我已经下架所有破解软件的下载链接了。
- 请问怎么下载呀
- 我保存的License在:https://gitlab.com/renfei/KingbaseES-V8-R3/-/tree/master/License ,开发版是长期有效的,只不过限制连接数,现在官网好像已经下线 V8R3 的下载页面了,其他版本我也不确定是否过期
- 这个版本的license有没有
- 序列号长度不对呀
- 优雅的源代码管理(二):Git 的工作原理
- 优雅的源代码管理(一):版本控制系统 VCS(Version Control System)与软件配置管理 SCM(Software Configuration Management)
- ChatGPT 开发商 OpenAI 买下极品域名 AI.com
- 火爆的 AI 人工智能 ChatGPT 国内注册教程、使用方式和收费标准
- 解决 SpringCloud 中 bootstrap.yml 不识别 @[email protected] 参数
- Cron表达式书写教程搞定Linux、Spring、Quartz的定时任务
- 阿里云香港可用区C发生史诗级故障
- 国产统信UOS服务器操作系统V20提供免费使用授权
- 开源站长推送工具效果评测推荐(百度/必应/谷歌)
- 获取公网IP服务「ip.renfei.net」升级增加地理定位数据字段公示