我有20 MB的文件。我只想在浏览器中以块/流的形式下载文件,这样,如果有另一个请求,很长一段时间内不会被阻止。
我还在长文件中看到了暂停行为。现在不需要。如果有人因为我好奇而知道这是如何工作的,可以解释一下。
我已将文件保存在DB中。当我收到下载文件的请求时。我将从DB获得文件。我将字节代码推入响应主体并将其发送到浏览器。在浏览器中,我创建了一个链接,并一次性下载了文件。
后端代码:
@GetMapping("/job-detail/{jobExecutionId}/file-detail")
public ResponseEntity<Resource> getFileDetail(@PathVariable final Long jobExecutionId) {
final FileDetailDto fileDetailDto =
fileTaskletService.getFileDetailByExecutionId(jobExecutionId);
return ResponseEntity.ok().contentType(new MediaType("text", "csv"))
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + fileDetailDto.getFileName() + "\"")
.body(new ByteArrayResource(fileDetailDto.getData()));
}
我想分块下载文件,以便其他请求也可以同时开始下载。
答案 0 :(得分:1)
从问题的措辞看来,您希望服务器框架为您设置以下标头,以使数据以分块的形式流回:
Transfer-Encoding: chunked
要执行此操作,您需要提供Spring资源,而该资源无法预先知道完整大小。您已使用ByteArrayResource
,其中已知全尺寸 并导致在响应中设置了Content-Length
标头,而未使用分块。
将代码更改为使用InputStreamResource
,该服务将使用分块的传输编码将响应流传输回客户端,并且没有内容长度。这是一个示例(未选中语法):
try(ByteArrayInputStream bis = new ByteArrayInputStream(fileDetailDto.getData())) {
return ResponseEntity.ok().contentType(new MediaType("text", "csv"))
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + fileDetailDto.getFileName() + "\"")
.body(new InputStreamResource(bis));
}
尽管这会给您带来分块的响应,但我不认为这是浏览器问题的根源,因为无论服务器如何提供,它们都具有异步流回数据的能力。