Spring StreamingResponseBody 中关闭客户端的错误处理

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)

那么是否可以在客户端关闭连接时停止与该请求相关的处理呢?否则,有用的资源就会被浪费。