java 返回InputStream Spring MVC后关闭ClosableHttpResponse

n3ipq98p  于 2023-03-06  发布在  Java
关注(0)|答案(1)|浏览(222)

我的控制器方法在响应体中返回InputStreamResource。我正在从TRY块中的ClosebleHttpResponse获取InputStream,并在FINALLY块中关闭ClosebleHttpResponse。

  • 问题是finally在返回之前被调用,并且没有机会从InputStream创建InputStreamResource,因为ClosebleHttpResponse已经关闭 *。

在这种情况下,可能的解决方案是什么?我可以在返回InputStreamResource后以某种方式关闭ClosableHttpResponse吗?我确实需要使用ClosableHttpClient,该方法应该返回一些

public ResponseEntity<InputStreamResource> getFileAsStream(@PathVariable("uuid") String uuid) throws IOException, InterruptedException {
        CloseableHttpResponse response = fileService.importFileByUuid(uuid);
        try {
            HttpEntity entity = response.getEntity();
            HttpHeaders responseHeaders = new HttpHeaders();
            responseHeaders.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(entity.getContentLength()));
            responseHeaders.add(HttpHeaders.CONTENT_TYPE, entity.getContentType().getValue());
            responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, response.getFirstHeader(HttpHeaders.CONTENT_DISPOSITION).getValue());

            if (entity != null) {
                InputStream inputStream = entity.getContent();
                InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
                return ResponseEntity.ok()
                            .headers(responseHeaders)
                            .body(inputStreamResource);
            }
            throw new IllegalStateException(String.format(
                    "Error during stream downloading, uuid = %s", uuid));
        } finally {
            response.close();
        }
    }
bvhaajcl

bvhaajcl1#

您始终可以创建从HttpEntity获取的InputStream的副本,并使用该副本创建在ResponseEntity中返回的InputStreamResource。这样,可以在返回ResponseEntity之前安全地关闭从HttpEntity获取的原始InputStream。

InputStream inputStream = entity.getContent();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
IOUtils.copy(inputStream, outputStream);
byte[] contentBytes = outputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(contentBytes);
InputStreamResource inputStreamResource = new InputStreamResource(byteArrayInputStream);

或者保存使用byte[]并使用它返回ByteArrayResource而不是InputStreamResource

相关问题