将文件从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();
- 如何在现有Java Web项目中添加AngularJS 2
- 如何将Cross Origin资源共享与Spring MVC 4.0.0 RESTful Webservice集成
- Angular Js在Java Spring mvc中发布日期错误请求
- 即使存在所有CORS标头,也会出现跨源资源共享问题
- 避免使用keycloak默认登录页面并使用项目登录页面
- Java Server – 使用POST发送Push到Google Firebase Cloud
- 通过Javascript缓存与在Server中设置HTTPResponse头之间有什么区别?
- 如何测试使用JavaScript开发的WebSocket
- 如何在angularjs中发送多个FIles以及表单数据