InputStream在Spring控制器中关闭

问题描述 投票:0回答:1

使用弹簧控制器,端点在主体响应中返回文件。我想确保不要使用“尝试资源”来获取资源泄漏,但是在邮递员中,我会收到一个错误:

“错误”:“内部服务器错误”,“ message”:“流关闭”,

Spring控制器中的代码片段:

InputStreamResource result;
ResponseEntity<Resource> response;
try(FileInputStream ios = new FileInputStream(file)){
    result = new InputStreamResource(ios);
    response = ResponseEntity.ok()
        .headers(/*some headers here*/)
        .contentLength(file.length())
        .contentType(/*some media type here*/)
        .body(result);
    logger.info("successfully created");
    return response;
} catch (IOException e) {
        //some code here..
}

有趣的是,在日志中我收到了成功消息,但是在邮递员或浏览器中(这是一个GET请求),我得到了一个错误。

而且如果不使用“ try-with-resource”,也可以,但是我担心那样会导致资源泄漏。

java stream spring-restcontroller try-with-resources
1个回答
0
投票

因为尝试资源将在close()之前调用return,将发生“流关闭”错误。一种简单的方法是将InputStreamResource的实例直接放在.body()中,Web上的大多数示例也都这样做。但是,我不确定是否会正确关闭资源以防止应用程序发生资源泄漏。

response = ResponseEntity.ok()
    .contentLength(file.length())
    .body(new InputStreamResource(new FileInputStream(file)));
return response;

另一种方法,如果要流式传输响应,则可以使用StreamingResponseBody

Interface StreamingResponseBody(从Spring网站引用)

这是一个功能接口,因此可以用作lambda表达式或方法引用的分配目标。

示例代码:

StreamingResponseBody responseBody = outputStream -> {
    Files.copy(file.toPath(), outputStream);
};

response.ok()
    .contentLength(file.length())
    .body(responseBody);
return response;
© www.soinside.com 2019 - 2024. All rights reserved.