解决SpringBoot jar包中的文件读取问题实现
更新时间:2020-08-27 09:48:39 作者:佚名 我要评论(0)
SpringBoot微服务已成为业界主流,从开发到部署都非常省时省力,但是最近小明开发时遇到一个问题:在代码中读取资源文件(比如word文档、导出模版等),本地开
前言
SpringBoot微服务已成为业界主流,从开发到部署都非常省时省力,但是最近小明开发时遇到一个问题:在代码中读取资源文件(比如word文档、导出模版等),本地开发时可以正常读取 ,但是,当我们打成jar包发布到服务器后,再次执行程序时就会抛出找不到文件的异常。
背景
这个问题是在一次使用freemarker模版引擎导出word报告时发现的。大概说一下docx导出java实现思路:导出word的文档格式为docx,事先准备好一个排好版的docx文档作为模版,读取解析该模版,将其中的静态资源替换再导出。
docx文档本身其实是一个压缩的zip文件,将其解压过后就会发现它有自己的目录结构。
问题
这个docx文档所在目录如下图所示:
在本地调试时,我使用如下方式读取:
import org.springframework.util.ResourceUtils; public static void main(String[] args) throws IOException { File docxTemplate = ResourceUtils.getFile("classpath:templates/docxTemplate.docx"); }
可以正常解析使用,但是打包发布到beta环境却不可用。抛出异常如下:
java.io.FileNotFoundException: class path resource [templates/docxTemplate.docx] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/usr/local/subject-server.jar!/BOOT-INF/classes!/templates/docxTemplate.docx
显而易见,这个异常告诉我们:没有找到文件,但是将jar包解压过后,发现这个文件是真真实实存在的。
那这到底是怎么回事呢?这压根难不倒我。我们要善于透过堆栈信息看本质。通过仔细观察堆栈信息,我发现此时的文件路径并不是一个合法的URL(文件资源定位符)。原来jar包中资源有其专门的URL形式: jar:<url>!/{entry} )。所以,此时如果仍然按照标准的文件资源定位形式
File f=new File("jar:file:……");
定位文件,就会抛出java.io.FileNotFoundException。
解决
虽然我们不能用常规操作文件的方法来读取jar包中的资源文件docxTemplate.docx,但可以通过Class类的getResourceAsStream()方法,即通过流的方式来获取 :
public static void main(String[] args) throws IOException { InputStream inputStream = WordUtil.class.getClassLoader().getResourceAsStream("templates/docxTemplate.docx"); }
拿到流之后,就可以将其转换为任意一个我们需要的对象,比如File、String等等,此处我要获取docxTemplate.docx下的目录结构,因此我需要一个File对象,代码举例如下:
import org.apache.commons.io.FileUtils; public static void main(String[] args) throws IOException { InputStream inputStream = WordUtil.class.getClassLoader().getResourceAsStream("templates/docxTemplate.docx"); File docxFile = new File("docxTemplate.docx"); // 使用common-io的工具类即可转换 FileUtils.copyToFile(inputStream,docxFile); ZipFile zipFile = new ZipFile(docxFile); Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries(); // todo 记得关闭流 }
结果
打包、发布至beta环境,亲测可用,问题完美解决。
到此这篇关于解决SpringBoot jar包中的文件读取问题实现的文章就介绍到这了,更多相关SpringBoot jar包文件读取内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
- 解决SpringBoot打成jar运行后无法读取resources里的文件问题
- SpringBoot如何读取war包jar包和Resource资源
您可能感兴趣的文章:
相关文章
mybatisplus报Invalid bound statement (not found)错误的解决方法
搭建项目时使用了mybatisplus,项目能够正常启动,但在调用mapper方法查询数据库时报Invalid bound statement (not found)错误。 以下为项目配置 pom文件 <depend2020-08-27Spring Cloud Admin健康检查 邮件、钉钉群通知的实现
本文主要介绍了Spring Cloud Admin的使用,分享给大家,具体如下: 源码地址:https://github.com/muxiaonong/Spring-Cloud/tree/master/cloudadmin Admin 简介 官方2020-08-27andorid 使用手势监听器GestureDetector遇到的不响应问题
做了一个项目,首页是使用ResideMenu实现,通过菜单栏里的菜单项创建的Fragment;所以一个Activtiy里就包含多个Fragment,想通过手势也能侧滑,就不用点击菜单按钮打2020-08-27SpringBoot中时间类型 序列化、反序列化、格式处理示例代码
【SpringBoot】 中时间类型 序列化、反序列化、格式处理 Date yml全局配置 spring: jackson: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss #配置POS2020-08-27
最新评论