将文件从SFTP直接下载到HTTP响应,而不使用中间文件

我正在尝试使用Java JSsch库通过SFTP下载文件。 我成功地将文件下载到本地目录。 **但是,我只需要将文件直接下载到浏览器而不提供任何本地目标路径(例如如何在Chrome中下载文件)。 我使用Spring控制器AngularJS Promise来捕获响应。 以下是我的代码。

@RequestMapping(value = "/downloadAttachment", method = RequestMethod.POST, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public void downloadAttachment( @RequestParam(value = "fileName") String fileName, @RequestParam(value = "filePath") String filePath, @RequestParam(value = "fileId") String fileId, HttpServletResponse response, Locale locale) throws Exception { InputStream is = null; if(!fileName.isEmpty() && !filePath.isEmpty() && !fileId.isEmpty()){ String directory = filePath; java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); JSch ssh = new JSch(); Session session = ssh.getSession(sftpLogin, sftpAddress, 22); session.setConfig(config); session.setPassword(sftpPassword); session.connect(); logger.info("Connection to server established"); Channel channel = session.openChannel("sftp"); channel.connect(); ChannelSftp sftp = (ChannelSftp) channel; sftp.cd(directory); is = sftp.get(fileName); channel.disconnect(); session.disconnect(); } IOUtils.copy(is, response.getOutputStream()); is.close(); response.getOutputStream().close(); response.flushBuffer(); } 

我不知道要下载的文件类型。 所以,我使用了MediaType.APPLICATION_OCTET_STREAM_VALUE 。 这给了我以下给出的例外情况。

java.io.IOException:管道已关闭java.io.PipedInputStream.read(未知源)java.io.PipedInputStream.read(未知源)com.jcraft.jsch.ChannelSftp.fill(ChannelSftp.java:2909)com.jcraft。 jsch.ChannelSftp.header(ChannelSftp.java:2935)com.jcraft.jsch.ChannelSftp.access $ 500(ChannelSftp.java:36)com.jcraft.jsch.ChannelSftp $ 2.read(ChannelSftp.java:1417)com.jcraft。 jsch.ChannelSftp $ 2.read(ChannelSftp.java:1364)org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)org.apache.commons.io.IOUtils.copy(IOUtils.java:999)

在从输入流实际读取任何内容之前断开通道和会话(存储在变量“is”中)。 请在IOUtils.copy()之后而不是之前调用以下行 –

 is.close(); channel.disconnect(); session.disconnect(); 

您也可以尝试直接打电话

 sftp.get(filename, response.getOutputSteam()); 

看看这里的文档

在尝试读取数据之前,无法关闭SFTP会话。

这是正确的代码:

 is = sftp.get(fileName); IOUtils.copy(is, response.getOutputStream()); channel.disconnect(); session.disconnect(); is.close();