前幾天在專案讀取resources目錄下的檔案時碰到一個小坑,明明在本地是可以正常運行的,但是一發到測驗環境就報錯了,說找不到檔案,報錯資訊是: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,
看了半天代碼感覺沒有問題,于是懷疑是打成專案jar包后和原專案存在差異導致的,于是我把的專案打成jar包,在本地直接除錯jar,果然發現問題所在,下面我將以一個自己的測驗專案api-test替代原來的公司專案來講述一下排查程序,
一、專案代碼
GetResourceTest:
public class GetResourceTest {
public InputStream getResource1() throws IOException {
File file = new DefaultResourceLoader().getResource("/template/qiankuan.ftl").getFile();
return Files.newInputStream(file.toPath());
}
public InputStream getResource2() throws IOException {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("/template/qiankuan.ftl");
Resource resource = resources[0];
return resource.getInputStream();
}
}
TestController:
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping(value = "https://www.cnblogs.com/getResource")
@ResponseBody
public void getResource() throws IOException {
GetResourceTest getResourceTest = new GetResourceTest();
getResourceTest.getResource1();
}
}
二、排查程序
1、首先使用Maven的install命令將專案打成jar包
命令執行成功后再target目錄下就生成了jar包
2、在Termininal里cd到target目錄下,然后執行下面的代碼,9992可以替換成其他埠
java -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9992 api-test-1.0.0-SNAPSHOT.jar
執行成功如下
3、添加遠程除錯
依次點擊選單Run,點擊Edit Configurations,點擊+,點擊Remote JVM Debug,埠后改成剛剛設定的9992,
4、請求介面
請求測驗介面,9991是專案原來的埠
127.0.0.1:9991/test/getResource
5、請求結果
請求果然報錯了,報錯和之前測驗環境的報錯一摸一樣,其實我們通過這個報錯已經可以大致上看出問題了,,,
6、斷點除錯
在請求的入口打上斷點開始斷點除錯
通過斷點除錯也可以看到這個檔案地址在原來的地址/template/qiankuan.ftl 前拼接了jar:file:/D:/Project/test/fhey-test/api-test/target/api-test-1.0.0-SNAPSHOT.jar!/BOOT-INF/classes!成為了jar:file:/D:/Project/test/fhey-test/api-test/target/api-test-1.0.0-SNAPSHOT.jar!/BOOT-INF/classes!/template/qiankuan.ftl,
然后在后面一段代碼中,resourceUrl.getProtocol()的回傳結果是"jar"而不是"file", 被判定為不是檔案然后拋出了一個FileNotFoundException例外,
三、解決方法
ResouceUtils.getFile()是專門用來加載非壓縮和Jar包檔案型別的資源,所以它根本不會去嘗試加載Jar中的檔案,要想加載Jar中的檔案,只要用可以讀取jar中檔案的方式加載即可,比如 可以采用ClassPathResource這種以流的形式讀取檔案的方式或者PathMatchingResourcePatternResolver來讀取檔案,
ClassPathResource classPathResource = new ClassPathResource("/template/qiankuan.ftl" );
InputStream inputStream = classPathResource.getInputStream();
或者
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("/template/qiankuan.ftl");
Resource resource = resources[0];
InputStream inputStream = resource.getInputStream();
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556520.html
標籤:其他
上一篇:Python web 框架對比:Flask vs Django
下一篇:返回列表