簡體   English   中英

Spring Boot 減少大型 CSV 文件的下載時間

[英]Spring Boot reduce download time of large CSV file

我有一個用於下載 CSV 文件的 API,該文件可能很大(最大 15MB)。 雖然響應時間相當長,但它在 Chrome 中給出了響應。 但是,在 Safari 中,它在 60 秒后顯示 504 Gateway timeout。 這是代碼:

public File dataToCSV(List<String[]> dataLines) throws IOException {

    File csvOutputFile = new File("supply_tracker_" + LocalDateTime.now() + ".csv");
    try (PrintWriter pw = new PrintWriter(csvOutputFile)) {
        dataLines.stream()
                .map(data -> String.join(",", data))
                .forEach(pw::println);
    }
    return csvOutputFile;
}

public ResponseEntity<Object> getFile(File csv) throws FileNotFoundException {
    if (csv != null) {
        InputStreamResource resource = new InputStreamResource(new FileInputStream(csv));
        long length = csv.length();
        boolean delete = csv.delete();
        if (delete) {
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", csv.getName()));
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(length)
                    .contentType(MediaType.parseMediaType("text/csv"))
                    .body(resource);
        }
    } else {
        return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);
    }
    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}

有哪些方法可以減少響應時間? 另外,是否有臨時解決方案可以在 Safari 上進行此操作? 前端在 React 中,API 適用於 axios 調用。

我建議使用ResponseBodyEmitter

您在這里遇到的大問題是您的客戶端必須等待響應 100% 准備好,然后服務器才能開始響應。

一旦這段等待時間超過讀取超時(通常為 30 秒),您將收到超時錯誤。 增加超時是一個非常短期的解決方案。

使用 ResponseBodyEmitter 允許您的服務器一次寫入一行響應,因此初始響應要快得多。

另一個探索的途徑是 Spring Reactive 庫。 我們的應用程序可以在 10、20 分鍾內毫無問題地返回許多 GB。

如果此 API 用於與其他 API 類似的最終用戶,則應考慮其他通信渠道來發送此文件,例如電子郵件或創建文件,上傳到某個位置並返回 URL 而不是文件,這樣用戶也可以多次下載它.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM