You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

REST控制器返回InputStreamResource时InputStream未释放问题咨询

Fixing InputStream Leak When Returning InputStreamResource in Spring REST Controller

Hey there! I totally get this frustration—resource leaks can be tricky to track down, especially with streaming responses in Spring. Let's break down why this happens and how to fix it properly.

Why the Leak Happens

The InputStreamResource class doesn't implement AutoCloseable, and Spring MVC's default message converters don't automatically close the underlying InputStream after sending the response. That means the stream from your GridFSDBFile stays open, tying up critical resources like database connections or file handles over time.

StreamingResponseBody is Spring's built-in solution for streaming responses, and it handles resource cleanup automatically. It’s purpose-built for this exact scenario, so it’s the cleanest fix. Here’s how to refactor your method:

@RequestMapping(value = "by-id/{attachmentId}", method = RequestMethod.GET)
public ResponseEntity<StreamingResponseBody> attachmentById(@PathVariable("attachmentId") String attachmentId) {
    GridFSDBFile file = service.getAttachment(attachmentId);
    // ... your existing code to set respHeaders ...

    StreamingResponseBody responseBody = outputStream -> {
        // Use try-with-resources to auto-close the input stream once done
        try (InputStream inputStream = file.getInputStream()) {
            // Copy stream data (use Apache Commons IO for simplicity, or implement your own loop)
            org.apache.commons.io.IOUtils.copy(inputStream, outputStream);
        } catch (IOException e) {
            // Handle exceptions appropriately—throw a runtime exception or custom exception
            throw new RuntimeException("Failed to stream attachment content", e);
        }
    };

    return new ResponseEntity<>(responseBody, respHeaders, HttpStatus.OK);
}
  • The try-with-resources block ensures the InputStream from GridFSDBFile is closed immediately after the data is copied.
  • Spring MVC takes care of closing the output stream once the response is fully sent to the client.

Solution 2: Custom Auto-Closable Resource (If You Must Use Resource)

If you have specific constraints requiring a Resource return type, you can create a custom implementation that handles stream closure. Here’s a quick example:

public class AutoClosingInputStreamResource extends InputStreamResource implements AutoCloseable {
    private final InputStream inputStream;

    public AutoClosingInputStreamResource(InputStream inputStream) {
        super(inputStream);
        this.inputStream = inputStream;
    }

    @Override
    public void close() throws IOException {
        inputStream.close();
    }
}

Then, you’d need to add a ResponseBodyAdvice or interceptor to call close() on the resource after the response is processed. This approach is more complex than using StreamingResponseBody, so only use it if you have no other option.

Key Takeaway

Stick with StreamingResponseBody for streaming file responses in Spring—it eliminates manual resource management and prevents leaks by design. It’ll keep your code clean and avoid those hard-to-debug resource exhaustion issues.

内容的提问来源于stack exchange,提问作者ASten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:02:03