Java Spring Boot基于JSch实现SSH远程文件直接流式下载返回
Spring Boot SFTP流式文件下载方案
问题背景
使用Java Spring Boot开发API时,需要实现通过接口下载远程SSH服务器上的文件,要求不将文件完整下载到API服务本地再返回给客户端,而是直接实现从SSH连接到接口响应的流式传输,待下载文件最大可达2GB,使用JSch实现SSH连接和文件获取。
方案可行性
该方案完全可行,核心是通过JSch直接获取远程文件的输入流,直接对接HTTP响应的输出流,全程不需要落地到API服务本地磁盘,内存占用仅由设置的缓冲区大小决定,完全支持2GB级别大文件下载。
更新:提问者已实现该功能且运行正常,感谢@Martin Prikryl的帮助。
实现代码
下载接口代码
@RequestMapping(value = "/endpoint-test/download-file-stream", method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) public static void sendFileInResponse (HttpServletResponse response) throws Exception { String path_file = "/opt/dir/file_test.txt"; // 该路径为远程服务器上的文件路径 ConexionJSch new_conection_to_filesystem = new ConexionJSch(); ChannelSftp channelSftp = new_conection_to_filesystem.setupJsch(); channelSftp.connect(); SftpATTRS data = channelSftp.lstat(path_file); long fsize = data.getSize(); try (InputStream inputStream = channelSftp.get(path_file)){ response.setContentType("application/octet-stream"); response.setContentLengthLong(fsize); response.setHeader("Content-Disposition", "inline;filename=test.bam"); OutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[2048]; int length = 0; while ((length = inputStream.read(buff)) > 0) { outputStream.write(buff, 0, length); outputStream.flush(); } inputStream.close(); response.setHeader("Cache-Control", "private"); response.setDateHeader("Expires", 0); } finally{ channelSftp.exit(); } }
JSch SFTP连接工具类
public class ConexionJSch { private final String remoteHost; private final String username; private final String password; public ConexionJSch() { this.remoteHost = "xxx.xxx.xxx.xxx"; this.username = "user"; this.password = "pass"; } public ChannelSftp setupJsch() throws JSchException { JSch jsch = new JSch(); jsch.setKnownHosts("/home/ubuntu_user/.ssh/known_hosts"); Session jschSession = jsch.getSession(username, remoteHost); jschSession.setPassword(password); jschSession.connect(); return (ChannelSftp) jschSession.openChannel("sftp"); } }
注意事项
- 需要确保SFTP连接超时、读取超时配置合理,避免大文件下载过程中连接被中断
- 缓冲区大小可以根据实际网络情况调整,通常设置为4KB~8KB可以兼顾性能和内存占用
- 工具类中的主机地址、用户名、密码建议放到配置文件中管理,不要硬编码在代码里
- 注意SFTP会话的释放,上述代码通过finally块确保channel正常退出,避免连接泄漏
内容的提问来源于stack exchange,提问作者MauriRamone
相关产品推荐
相关产品推荐

