Springboot整合sftp
一、网址
官网:http://www.jcraft.com/jsch/
博客:https://blog.csdn.net/qq_39361915/article/details/112762028
二、介绍
sftp(Secure File Transfer Protocol)是一种安全的文件传送协议,是ssh内含协议,也就是说只要sshd服务器启动了,sftp就可使用,不需要额外安装,它的默认端口和SSH一样为22。
sftp通过使用加密/解密技术来保障传输文件的安全性,因此sftp的传输效率比普通的FTP要低,但sftp的安全性要比ftp高,因此sftp通常用于报表、对账单等对安全性要求较高的场景。
三、代码
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
private boolean createDir(ScpConnectEntity scpConnectEntity) throws JSchException {
JSch jsch = new JSch();
com.jcraft.jsch.Session sshSession = null;
Channel channel = null;
try {
sshSession = jsch.getSession(scpConnectEntity.getUserName(), scpConnectEntity.getUrl(), scpConnectEntity.getPort());
sshSession.setPassword(scpConnectEntity.getPassWord());
sshSession.setConfig("kex", "diffie-hellman-group1-sha1");//设置传输的DH私钥内容:
sshSession.setConfig("StrictHostKeyChecking", "no");
sshSession.connect();
channel = sshSession.openChannel("sftp");
channel.connect();
} catch (JSchException e) {
e.printStackTrace();
throw new JSchException("SFTP连接服务器失败" + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
ChannelSftp channelSftp = (ChannelSftp) channel;
if (isDirExist(scpConnectEntity.getFilePath(), channelSftp)) {
channel.disconnect();
channelSftp.disconnect();
sshSession.disconnect();
return true;
} else {
String[] pathArry = scpConnectEntity.getFilePath().split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
try {
if (isDirExist(filePath.toString(), channelSftp)) {
channelSftp.cd(filePath.toString());
} else {
// 建立目录
channelSftp.mkdir(filePath.toString());
// 进入并设置为当前目录
channelSftp.cd(filePath.toString());
}
} catch (SftpException e) {
e.printStackTrace();
throw new JSchException("SFTP无法正常操作服务器" + e.getMessage());
}
}
}
channel.disconnect();
channelSftp.disconnect();
sshSession.disconnect();
return true;
}
private boolean isDirExist(String directory, ChannelSftp channelSftp) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = channelSftp.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
Springboot整合scp
scp是 secure copy 的缩写,相当于cp命令 + SSH。它的底层是 SSH 协议,默认端口是22,相当于先使用ssh命令登录远程主机,然后再执行拷贝操作。
scp主要用于以下三种复制操作。
- 本地复制到远程。
- 远程复制到本地。
- 两个远程系统之间的复制。
使用scp传输数据时,文件和密码都是加密的,不会泄漏敏感信息。
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>262</version>
</dependency>
private void remoteUploadFile(ScpConnectEntity scpConnectEntity, File file) throws JSchException, IOException {
Connection connection = null;
SCPOutputStream scpo = null;
FileInputStream fis = null;
try {
createDir(scpConnectEntity);
} catch (JSchException e) {
throw e;
}
try {
connection = new Connection(scpConnectEntity.getUrl(), scpConnectEntity.getPort());
connection.connect();
if (!connection.authenticateWithPassword(scpConnectEntity.getUserName(), scpConnectEntity.getPassWord())) {
throw new RuntimeException("SSH连接服务器失败");
}
SCPClient scpClient = connection.createSCPClient();
scpo = scpClient.put(scpConnectEntity.getRemoteFileName(), file.length(), scpConnectEntity.getFilePath(), "0666");
fis = new FileInputStream(file);
byte[] buf = new byte[1024];
int hasMore = fis.read(buf);
while (hasMore != -1) {
scpo.write(buf);
hasMore = fis.read(buf);
}
} catch (IOException e) {
e.printStackTrace();
throw new IOException("SSH上传文件至服务器出错" + e);
} catch (Exception e) {
logger.error("remote upload file:"+e.getMessage());
} finally {
if (null != fis) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != scpo) {
try {
scpo.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != connection) {
connection.close();
}
}
}
相同点、不同点
相同点:都是使用SSH协议来传输文件的
不同点:SFTP能断点续传,SCP则不能