开箱即用,直接上代码
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Sftp工具类
*
* @author hcf
* @date 2021/6/26 16:38
*/
@Slf4j
public class SftpUtils {
private static final String NO_LOGIN = "0";
/**
* 向SFTP服务器上传文件
*
* @param host SFTP服务器ip
* @param port SFTP服务器端口
* @param username SFTP登录账号
* @param password SFTP登录密码
* @param privateKey 免密私钥路径
* @param loginType 登录方式
* @param filePath 远程存放路径
* @param filename 文件名
* @param is 输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFileSftp(String host, int port, String username, String password, String privateKey,
String loginType, String filePath, String filename, InputStream is) {
JSch jsch = new JSch();
try {
// 获取sshSession 账号-ip-端口
Session sshSession = jsch.getSession(username, host, port);
if (StringUtils.isNotBlank(privateKey) && StringUtils.equals(NO_LOGIN, loginType)) {
jsch.addIdentity(privateKey);
} else {
sshSession.setPassword(password);
}
return uploadFileSftp(sshSession, filePath, filename, is);
} catch (Exception e) {
log.error("SFTP服务器 文件上传失败 失败原因:{}", e.getMessage(), e);
return false;
}
}
private static boolean uploadFileSftp(Session sshSession, String filePath,
String filename, InputStream is) throws Exception {
boolean success = true;
FTPClient ftp = new FTPClient();
try {
ChannelSftp sftp = connectServer(sshSession, ftp, filePath);
sftp.put(is, filename);
is.close();
sftp.quit();
} catch (Exception e) {
log.error(" SFTP服务器 文件上传失败 失败原因:{}", e.getMessage(), e);
throw new Exception(" SFTP服务器文件上传失败,失败原因:" + e.getMessage());
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
log.error("SFTP服务器 关闭失败 失败原因:{}", e.getMessage(), e);
success = false;
}
}
if (sshSession.isConnected()) {
sshSession.disconnect();
}
}
return success;
}
private static ChannelSftp connectServer(Session sshSession, FTPClient ftp, String filePath) throws Exception {
Properties sshConfig = new Properties();
// 严格主机密钥检查
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
// 开启sshSession链接
sshSession.connect();
// 获取sftp通道
Channel channel = sshSession.openChannel("sftp");
// 开启
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;
// 设置为被动模式
ftp.enterLocalPassiveMode();
sftp.cd(filePath);
return sftp;
}
/**
* 向SFTP服务器上传大文件
*
* @param host SFTP服务器ip
* @param port SFTP服务器端口
* @param username SFTP登录账号
* @param password SFTP登录密码
* @param filePath 远程存放路径
* @param filename 文件名
* @param clientFile 本地文件
* @return 成功返回true,否则返回false
*/
public static boolean uploadBigFileSftp(String host, int port, String username, String password, String privateKey,
String loginType, String filePath, String filename, String clientFile) {
JSch jsch = new JSch();
try {
// 获取sshSession 账号-ip-端口
Session sshSession = jsch.getSession(username, host, port);
if (StringUtils.isNotBlank(privateKey) && StringUtils.equals(NO_LOGIN, loginType)) {
jsch.addIdentity(privateKey);
} else {
sshSession.setPassword(password);
}
return uploadBigFileSftp(sshSession, filePath, filename, clientFile);
} catch (Exception e) {
log.error("SFTP服务器 文件上传失败 失败原因:{}", e.getMessage(), e);
return false;
}
}
private static boolean uploadBigFileSftp(Session sshSession, String filePath,
String filename, String clientFile) throws Exception {
boolean success = true;
FTPClient ftp = new FTPClient();
try {
ChannelSftp sftp = connectServer(sshSession, ftp, filePath);
sftp.put(new FileInputStream(clientFile), filename);
sftp.quit();
} catch (Exception e) {
log.error("SFTP服务器上传文件 {} 失败 失败原因:{}", clientFile, e.getMessage(), e);
throw new Exception("SFTP服务器上传文件 " + clientFile + " 失败 失败原因:" + e.getMessage());
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
log.error("SFTP服务器 关闭失败 失败原因:{}", e.getMessage(), e);
success = false;
}
}
if (sshSession.isConnected()) {
sshSession.disconnect();
}
}
return success;
}
/**
* 从 SFTP 服务器下载文件
*
* @param host SFTP服务器ip
* @param port SFTP服务器端口
* @param username SFTP登录账号
* @param password SFTP登录密码
* @param privateKey 密钥路径
* @param loginType 登录方式
* @param filePath 文件路径
* @param filename 文件名
* @param clientFilePath 下载路径
* @return 本地路径
*/
public static String downLoadFileSftp(String host, int port, String username, String password, String privateKey,
String loginType, String filePath, String filename, String clientFilePath) {
FTPClient ftp = new FTPClient();
JSch jsch = new JSch();
try {
File file = new File(clientFilePath);
if (!file.exists()) {
file.mkdirs();
}
// 获取sshSession 账号-ip-端口
Session sshSession = jsch.getSession(username, host, port);
if (StringUtils.isNotBlank(privateKey) && StringUtils.equals(NO_LOGIN, loginType)) {
sshSession.setPassword(privateKey);
} else {
sshSession.setPassword(password);
}
ChannelSftp sftp = connectServer(sshSession, ftp, filePath);
FileOutputStream fos = new FileOutputStream(clientFilePath + File.separator + filename);
sftp.get(filename, fos);
fos.close();
return clientFilePath;
} catch (Exception e) {
log.error("SFTP服务器 文件上传失败 失败原因:{}", e.getMessage(), e);
return null;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
log.error("SFTP服务器 关闭失败 失败原因:{}", e.getMessage(), e);
}
}
}
}
}