Sti*_*ijn 6 java spring spring-boot
我想知道是否有一种方法可以查明客户端是否关闭了一段StreamingResponseBody时间内数据仍在写入输出流的连接。我的 Spring Boot 控制器如下所示:
@RestController
public class MyController {
@PostMapping(value = "/zip")
public ResponseEntity<StreamingResponseBody> zip(HttpServletResponse response) {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment;filename=download.zip");
StreamingResponseBody responseBody = outputStream -> {
try (ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
// loop over files
final ZipEntry zipEntry = new ZipEntry(path);
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = bufferedInputStream.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
zipOut.closeEntry();
} catch (IOException e) {
// error handling
}
}
return new ResponseEntity<>(responseBody, HttpStatus.OK);
}
}
Run Code Online (Sandbox Code Playgroud)
该应用程序获取一些文件并将它们放入 ZIP 文件中作为响应。在正常操作下,该应用程序运行良好。
如果客户端中止 ZIP 文件的下载,应用程序会继续将文件放入 ZIP 中,但最终会失败ClientAbortException(几分钟后)。这是详细的错误消息:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351)
at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:776)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:681)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:386)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:364)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:645)
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:645)
at java.util.zip.DeflaterOutputStream.deflate(DeflaterOutputStream.java:253)
at java.util.zip.DeflaterOutputStream.write(DeflaterOutputStream.java:211)
at java.util.zip.ZipOutputStream.write(ZipOutputStream.java:331)
Run Code Online (Sandbox Code Playgroud)
那么是否可以在客户端关闭连接时停止与该请求相关的处理呢?否则,有用的资源就会被浪费。