1. 程式人生 > >SpringBoot 項目打包後獲取不到resource下資源的解決

SpringBoot 項目打包後獲取不到resource下資源的解決

log 環境 打包成 NPU request 訪問 cert 就是 不用

SpringBoot 項目打包後獲取不到resource下資源的解決

在項目中有幾個文件需要下載,然後不想暴露真實路徑,又沒有CDN,便決定使用接口的方式來獲取文件。最初的時候使用了傳統的方法來獲取文件路徑,發現不行。查找資料後發現是SpringBoot框架導致的,得用另外的方法:

//聽說在linux系統中會失效。
//不用聽說了,就是會掛,血的教訓
String path = ResourceUtils.getURL("classpath:").getPath();

//此方法返回讀取文件字節的方式在linux系統中無異。
InputStream inputStream  = getClass().getClassLoader().getResourceAsStream("RSA/privateKey.txt");

//聲明io的resources對象也可訪問
Resource resource = new ClassPathResource(uploadPath+privateKeyFileName);

// 此方法用來寫文件或上傳文件在本項目中指定路徑。
String privateKeyFileStr = request.getSession().
            getServletContext().getRealPath("RSA/privateKey.txt"); 

剛開始的時候用的就是第一種方法,初生牛犢不怕虎吧,說不定在linux上就行呢,本地環境測試通過,然後再上linux測試環境,不出意外,掛了。

//聽說在linux系統中會失效。
//不用聽說了,就是會掛,血的教訓
String path = ResourceUtils.getURL("classpath:").getPath();

乖乖使用其他的方法,這裏選擇使用了第三種方法:

public byte[] downloadServerCrt() {
    try {
        Resource resource = new ClassPathResource("static/syslog/cert/server.crt");
        byte[] bytes = readFileInBytesToString(resource);
        return bytes;
    } catch (Exception e) {
        throw new Exception("下載失敗" + e.getMessage());
    }
}

這裏還有一個坑,也是踩過了才知道,這邊的resource是Resource類型的變量,剛開始我使用了resource.getFile()方法獲取到File對象然後再采用IO流進行操作,即:

File file = resource.getFile();
DataInputStream isr = new DataInputStream(resource.getInputStream());
...

在IDE中運行是完全沒有問題的,但使用mvn打包成jar包後,再運行就會提示ERROR:

java.io.FileNotFoundException: class path resource [static/syslog/cert/server.crt] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/home/admin/dtlog-web/lib/log-web-3.0.2.jar!/static/syslog/cert/server.crt

後來查閱了資料說:一旦打成jar包後,使用File是訪問不到資源的內容的,推薦使用getInputStream()的方法,修改後:

InputStream in = resource.getInputStream();
DataInputStream isr = new DataInputStream(in);
...

測試沒有問題,bug解決。

參考資料

Springboot 訪問resources目錄文件方式

Classpath resource not found when running as jar

SpringBoot 項目打包後獲取不到resource下資源的解決