不使用中间文件直接从SFTP下载文件到HTTP响应
Downloading file from SFTP directly to HTTP response without using intermediate file
我正在尝试使用 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: Pipe closed
java.io.PipedInputStream.read(Unknown Source)
java.io.PipedInputStream.read(Unknown Source)
com.jcraft.jsch.ChannelSftp.fill(ChannelSftp.java:2909)
com.jcraft.jsch.ChannelSftp.header(ChannelSftp.java:2935)
com.jcraft.jsch.ChannelSftp.access0(ChannelSftp.java:36)
com.jcraft.jsch.ChannelSftp.read(ChannelSftp.java:1417)
com.jcraft.jsch.ChannelSftp.read(ChannelSftp.java:1364)
org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
在尝试读取数据之前不能关闭 SFTP 会话。
这是正确的代码:
is = sftp.get(fileName);
IOUtils.copy(is, response.getOutputStream());
channel.disconnect();
session.disconnect();
is.close();
在实际从输入流(存储在变量 "is" 中)读取任何内容之前,您正在断开通道和会话。请在 IOUtils.copy() 之后而不是 -
之前调用以下行
is.close();
channel.disconnect();
session.disconnect();
您也可以尝试直接调用
sftp.get(filename, response.getOutputSteam());
查看文档here
我正在尝试使用 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: Pipe closed java.io.PipedInputStream.read(Unknown Source) java.io.PipedInputStream.read(Unknown Source) com.jcraft.jsch.ChannelSftp.fill(ChannelSftp.java:2909) com.jcraft.jsch.ChannelSftp.header(ChannelSftp.java:2935) com.jcraft.jsch.ChannelSftp.access0(ChannelSftp.java:36) com.jcraft.jsch.ChannelSftp.read(ChannelSftp.java:1417) com.jcraft.jsch.ChannelSftp.read(ChannelSftp.java:1364) org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025) org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
在尝试读取数据之前不能关闭 SFTP 会话。
这是正确的代码:
is = sftp.get(fileName);
IOUtils.copy(is, response.getOutputStream());
channel.disconnect();
session.disconnect();
is.close();
在实际从输入流(存储在变量 "is" 中)读取任何内容之前,您正在断开通道和会话。请在 IOUtils.copy() 之后而不是 -
之前调用以下行is.close();
channel.disconnect();
session.disconnect();
您也可以尝试直接调用
sftp.get(filename, response.getOutputSteam());
查看文档here