Spring集成FeignClient实现PDF下载仅单次生效问题求助
问题根因
核心故障原因是控制器方法中提前关闭了待读取的PDF输入流:
Spring MVC中StreamingResponseBody对应的异步流处理逻辑,不会和控制器方法在同一个线程执行。控制器方法定义完返回体后直接执行in.close()关闭输入流,等Spring后续调度异步线程执行IOUtils.copy逻辑时,输入流已经处于关闭状态,无法读取到任何内容。
首次请求能够成功属于偶发现象,通常是因为首次请求的异步调度优先级更高,输入流关闭前已经完成了流拷贝操作。
修复方案
- 删除控制器方法中提前关闭输入流的
in.close()代码行 - 用try-with-resources语法托管输入流、输出流的关闭逻辑,既保证资源正常释放,也避免流在读取前被关闭,修复后的控制器代码如下:
@RestController @RequiredArgsConstructor public class Controller { private final UseCase useCase; public ResponseEntity<StreamingResponseBody> getDocument() throws IOException { final InputStream in = useCase.getDocument(); StreamingResponseBody streamingResponse = out -> { // try-with-resources会在拷贝完成后自动关闭输入、输出流 try (InputStream inputStream = in; OutputStream outputStream = out) { IOUtils.copy(inputStream, outputStream); outputStream.flush(); } }; return ResponseEntity.ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_PDF_VALUE) .body(streamingResponse); } }
如果使用JDK9及以上版本,try-with-resources可直接引用已声明的变量,简化为try (in; out)即可。
验证说明
修复后多次请求都会在异步线程中正常读取输入流内容返回,不会出现空响应、无法打开PDF的问题,同时也不会产生输入输出资源泄漏的风险。
内容的提问来源于stack exchange,提问作者thmasker
相关产品推荐
相关产品推荐

