【问题标题】:StreamingResponseBody returning empty fileStreamingResponseBody 返回空文件
【发布时间】:2019-10-12 07:12:29
【问题描述】:

我正在尝试使用 Springboot 创建一个休息服务来从存储库下载文件。

我正在尝试返回一个带有 StreamingResponseBody 的 ResponseEntity,以将我从存储库中获取的文件作为 InputStream 返回。

这是我当前的代码:


@GetMapping(path = "/downloadFile")
    public ResponseEntity<StreamingResponseBody> downloadFile(@RequestParam(value = "documentId") String documentId,
            HttpServletRequest request, HttpServletResponse response) throws InterruptedException, IOException {

        InputStream is = downloadService.getDocument(documentId);

        StreamingResponseBody out = outputStream -> {

            outputStream.write(IOUtils.toByteArray(is));
        };

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "text/csv");
        headers.add("Content-Disposition", "attachment; filename=" + documentId);
        headers.add("Pragma", "no-cache");
        headers.add("Cache-Control", "no-cache");

        return (new ResponseEntity<>(out, headers, HttpStatus.OK));

    }

当我直接使用浏览器或邮递员使用此端点时,下载的文件为空。 我知道 OutputStream 是异步写入的(在配置类中启用了异步)。

如何使用此服务并完全写入文件,它来自我正在使用的存储库的方式? (如果可能,使用 Postman,仅用于测试目的)

我是否正确构建了服务?

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    我稍微修改了代码,在我的documentId中是要下载的文件的名称。我已经测试过了,它工作正常。检查下面的代码。

    @GetMapping(path = "/downloadFile")
    public ResponseEntity<StreamingResponseBody> downloadFile(
          @RequestParam(value = "documentId") String documentId,
          HttpServletRequest request,
          HttpServletResponse response)
          throws InterruptedException, IOException {
        String dirPath = "E:/sure-delete/"; //Directory having the files
        InputStream inputStream = new FileInputStream(new File(dirPath + documentId));
        final StreamingResponseBody out =
            outputStream -> {
              int nRead;
              byte[] data = new byte[1024];
              while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                System.out.println("Writing some bytes of file...");
                outputStream.write(data, 0, nRead);
              }
            };
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "text/csv");
        headers.add("Content-Disposition", "attachment; filename=" + documentId);
        headers.add("Pragma", "no-cache");
        headers.add("Cache-Control", "no-cache");
        return ResponseEntity.ok().headers(headers).body(out);
      }
    

    【讨论】:

    • 嗨桑比特。非常感谢你帮助我。但问题仍然存在。我使用端点,文件以空或少量字节(如 5/10 字节)下载。我添加了日志,我注意到流是在不同的线程中写入的,但这是在文件已经下载之后发生的。我可能在异步配置上遗漏了一些东西,对吧?
    • @RuiBessa,我试图从stats.govt.nz/large-datasets/csv-files-for-download这个位置下载一个csv文件。文件大小 3.4 mb。上面的代码工作得很好。我也测试过。
    • 对我不起作用。我通过 axios 发送了一个请求,response.data 对我来说也是空白的。
    猜你喜欢
    • 1970-01-01
    • 2016-12-21
    • 2019-10-16
    • 2016-11-07
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    相关资源
    最近更新 更多