Spring Boot啟動後讀取jar包內部檔案

JasmineR發表於2019-04-17

前言

專案很少會將一些需要讀取的檔案放在專案內部,而是放在特定的檔案伺服器存取(系統伺服器外部);但也不排除一些小專案,只有極其少量的檔案讀取服務(如僅僅下載一個簡單的模板檔案),配置檔案伺服器就會顯得有些大材小用,就會將這些模板檔案放入專案內部進行統一打包部署;

背景

一個簡單的專案,使用者需要根據特定格式上傳一份檔案進行資料匯入處理,但並沒有配置檔案伺服器什麼的,只能將模板檔案放入系統中讀取下載;在開發環境中直接路徑是可以讀取(未打包),釋出後發現不能讀取對應的模板檔案,網上搜查了一番,解決該問題。

解決方法

模板檔案位置在靜態目錄下(直接上獲取檔案程式碼)

  • 開發環境程式碼(開發可用,釋出不可用)
/**
     * 客戶資訊匯入模板下載
     *
     * @return 跳轉頁面
     */
    @GetMapping("/template_download")
    @RequiresPermissions("customer:template_download")
    public ResponseEntity<Resource> downloadTemplate() throws FileNotFoundException {
        // Spring 自帶ResourceUtils路徑讀取
        //File file = new File("static/模板.xlsx");   // 怎麼讀取都是失敗
        File file = ResourceUtils.getFile("classpath:static/模板.xlsx");
        InputStream inputStream = new FileInputStream(file);
        Resource resource = new InputStreamResource(inputStream);
        try {
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment;fileName=" + URLEncoder.encode("客戶模板.xlsx", "utf-8"))
                    .body(resource);
        } catch (UnsupportedEncodingException e) {
            log.error("檔案下載異常");
            throw new ExportDataException("檔案下載異常");
        }
    }
複製程式碼
  • 開發/釋出環境(正確解法)
 /**
     * 客戶資訊匯入模板下載
     *
     * @return 跳轉頁面
     */
    @GetMapping("/template_download")
    @RequiresPermissions("customer:template_download")
    public ResponseEntity<Resource> downloadTemplate() throws FileNotFoundException {
        // 直接工程內部相對路徑(must)
        File file = new File("src/main/resources/static/模板.xlsx");
        InputStream inputStream = new FileInputStream(file);
        // 使用CLASSPATH讀取檔案(路徑必須/)
        // File file = new File(this.getClass().getResource("/static/模板.xlsx").toURI());
//        InputStream inputStream = this.getClass().getResourceAsStream("/static/模板.xlsx");

        Resource resource = new InputStreamResource(inputStream);
        try {
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment;fileName=" + URLEncoder.encode("客戶模板.xlsx", "utf-8"))
                    .body(resource);
        } catch (UnsupportedEncodingException e) {
            log.error("檔案下載異常");
            throw new ExportDataException("檔案下載異常");
        }
    }
複製程式碼

相關文章