javascript
SpringBoot项目打包成jar后,使用ClassPathResource获取classpath(resource)下文件失败
我在讀取郵件模板的時(shí)候,本地測(cè)試使用ClassPathResource都可以正常讀取,但打包成jar包傳到服務(wù)器上就無(wú)法獲取了,報(bào)錯(cuò)信息是: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,話不多說(shuō),先看正確的獲取方法:使用PathMatchingResourcePatternResolver。
String txt = ""; ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("templates/layout/email.html"); Resource resource = resources[0]; //獲得文件流,因?yàn)樵趈ar文件中,不能直接通過(guò)文件資源路徑拿到文件,但是可以在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();然后,想知道更多的咱們就繼續(xù)看看是怎么回事,如果只是為了解決問(wèn)題,那就可以忽略下面的內(nèi)容了。
為了老夫好奇的心,我們繼續(xù)探索下去,到底是怎么回事?我們先看看之前的代碼:
String txt = ""; Resource resource = new ClassPathResource("templates/layout/email.html"); txt = fileUtil.readfile(resource.getFile().getPath());其實(shí)這是一個(gè)jar包發(fā)布的大坑,相信很多小伙伴遇到了讀取文件的問(wèn)題,其實(shí)使用getFile()的時(shí)候的坑,為了弄明白到底是咋回事,我進(jìn)行了跟蹤,結(jié)果返回的是一個(gè)Jar協(xié)議地址:jar:file:/xxx/xx.jar!/xxxx。
?
然后繼續(xù)跟蹤到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());}} }因?yàn)閞esourceUrl.getProtocol()不是file,而是 jar,這樣就拋出了一個(gè)FileNotFoundException異常。
ResouceUtils.getFile()是專(zhuān)門(mén)用來(lái)加載非壓縮和Jar包文件類(lèi)型的資源,所以它根本不會(huì)去嘗試加載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();解決方案二:通過(guò)指定類(lèi)所在的目錄來(lái)指定模板所在根路徑
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項(xiàng)目打包成jar后讀取文件的大坑,使用ClassPathResource獲取classpath下文件失敗 - Posts - 任霏的博客
參考文章2:打包成jar后讀取文件的大坑:使用ClassPathResource獲取classpath下文件失敗_趕路人兒的博客-CSDN博客?
參考文章3:freemaker模板位置ClassTemplateLoader的絕對(duì)路徑相對(duì)路徑設(shè)置方法_機(jī)械手學(xué)Java的博客-CSDN博客_freemarker 模板路徑
總結(jié)
以上是生活随笔為你收集整理的SpringBoot项目打包成jar后,使用ClassPathResource获取classpath(resource)下文件失败的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: My Fifteenth Page -
- 下一篇: 【一】ArcGIS API for Ja