【问题标题】:Spring Boot reduce download time of large CSV fileSpring Boot 减少大型 CSV 文件的下载时间
【发布时间】:2021-07-02 09:07:25
【问题描述】:

我有一个用于下载 CSV 文件的 API,该文件可能很大(最大 15MB)。虽然响应时间很长,但它在 Chrome 中给出了响应。但是,在 Safari 中,它会在 60 秒后显示 504 网关超时。这是代码:

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 调用。

【问题讨论】:

  • 您可以查看 Spring Boot 的请求超时配置 - 但在我看来,Safari 客户端正在超时。在返回客户端之前压缩文件会使包更小,并应减少下载时间。

标签: java spring-boot csv spring-mvc response-time


【解决方案1】:

我建议使用ResponseBodyEmitter

您遇到的最大问题是您的客户端必须等待响应准备好 100%,然后服务器才能开始响应。

一旦这段等待时间超过读取超时(通常为 30 秒),您将收到超时错误。增加超时是一个非常短期的解决方案。

使用 ResponseBodyEmitter 允许您的服务器一次写入一行响应,因此初始响应更快。

另一个探索的途径是 Spring Reactive 库。我们的应用可以在 10、20 分钟内返回数 GB 而不会出现问题。

【讨论】:

  • 您能否提供一个示例或一些资源,我可以在其中找到如何使用ResponseBodyEmitter 流式传输文件和 JSON(用于另一个用例),以防您以前使用过它。
  • 快速谷歌搜索显示了几个例子。这是一个:howtodoinjava.com/spring-boot2/rest/…
【解决方案2】:

如果此 API 是针对最终用户的,与其他 API 一样,应考虑其他通信渠道来发送此文件,如电子邮件或创建文件,上传到某个位置并返回 URL 而不是文件,这样用户可以下载它也多次。

【讨论】:

  • 很遗憾,这不是客户想要的
猜你喜欢
  • 2015-02-04
  • 2020-03-20
  • 2022-01-23
  • 2021-05-01
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
相关资源
最近更新 更多