第一步,導包
<!-- sftp -->
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
第二步,創建sftpConfig的實體類
//密鑰地址
private String privateKeyPath;
//口令
private String passphrase;
//目標服務器ip
private String ip;
//目標服務器端口號
private Integer port;
//目標服務器用戶名(root)
private String username;
//目標服務器登錄密碼
private String pwd;
private String path;
private String baseDir;
第三步,創建SftpChannel,以密鑰或者用戶密碼登錄目標服務器
我這裏用的賬號密碼登錄目標服務器,同時給出密鑰登錄方式
public class SftpChannel {
Session session = null;
Channel channel = null;
// 端口默認爲22
public static final int SFTP_DEFAULT_PORT = 22;
/** 利用JSch包實現SFTP下載、上傳文件(祕鑰方式登陸) */
public ChannelSftp connectByIdentity(SftpConfig sftpConfig) throws JSchException {
JSch jsch = new JSch();
int port = SFTP_DEFAULT_PORT;
// 設置密鑰和密碼
// 支持密鑰的方式登陸,只需在jsch.getSession之前設置一下密鑰的相關信息就可以了
if (StringUtils.isNotBlank(sftpConfig.getPrivateKeyPath())) {
if (StringUtils.isNotBlank(sftpConfig.getPassphrase())) {
// 設置帶口令的密鑰
jsch.addIdentity(sftpConfig.getPrivateKeyPath(), sftpConfig.getPassphrase());
} else {
// 設置不帶口令的密鑰
jsch.addIdentity(sftpConfig.getPrivateKeyPath());
}
}
if (sftpConfig.getPort() != null) {
port = Integer.valueOf(sftpConfig.getPort());
}
if (port > 0) {
// 採用指定的端口連接服務器
session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), port);
} else {
// 連接服務器,採用默認端口
session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp());
}
if (session == null) {
throw new JSchException("session爲空,連接失敗");
}
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
session.setConfig(sshConfig);
session.setTimeout(30000);
session.connect();
// 創建sftp通信通道
channel = (Channel) session.openChannel("sftp");
channel.connect();
return (ChannelSftp) channel;
}
/** 利用JSch包實現SFTP下載、上傳文件(用戶名密碼方式登陸) */
public ChannelSftp connectByPwd(SftpConfig sftpConfig) throws JSchException {
JSch jsch = new JSch();
int port = SFTP_DEFAULT_PORT;
if (sftpConfig.getPort() != null) {
port = Integer.valueOf(sftpConfig.getPort());
}
System.out.println("目標服務器用戶名=" + sftpConfig.getUsername() + "--目標服務器IP=" + sftpConfig.getIp());
System.out.println("目標服務器密碼=" + sftpConfig.getPwd());
if (port > 0) {
// 採用指定的端口連接服務器
session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), port);
} else {
// 連接服務器,採用默認端口
session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp());
}
if (session == null) {
throw new JSchException("session爲空,連接失敗");
}
// 設置登陸主機的密碼
session.setPassword(sftpConfig.getPwd());// 設置密碼
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
session.setConfig(sshConfig);
session.setTimeout(30000);
session.connect();
// 創建sftp通信通道
channel = (Channel) session.openChannel("sftp");
channel.connect();
return (ChannelSftp) channel;
}
//上傳或下載完成後一定記得調用此方法關閉通道
public void closeChannel() {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
第四步,上傳文件的util
public class SFTPUtil {
/*
* 獲取sftp對象
*/
//這裏的paran參數相當於構造一個json格式的sftpconfig對象字符串,將其格式化後轉爲對象
//格式"{privateKeyPath:'',passphrase:''}"將sftpconfig的參數注入
public static SftpConfig getSftpObj(String param) {
SftpConfig sftpConfig = new SftpConfig();
if (StringUtils.isNotBlank(param)) {
JSONObject jsonObj = JSONObject.fromObject(param);
sftpConfig = (SftpConfig) JSONObject.toBean(jsonObj, SftpConfig.class);
}
return sftpConfig;
}
/** sftp 上傳 */
public static boolean upload(SftpConfig config, String baseDir, String fileName, String filePath) {
// logger.info();
System.out.println("路徑:baseDir=" + baseDir);
SftpChannel sftpChannel = new SftpChannel();
ChannelSftp sftp = null;
try {
if (StringUtils.isNotBlank(config.getPrivateKeyPath())) {
sftp = sftpChannel.connectByIdentity(config);
} else {
sftp = sftpChannel.connectByPwd(config);
}
if (sftp.isConnected()) {
//System.out.println("連接服務器成功");
} else {
//System.out.println("連接服務器失敗");
return false;
}
// 檢查路徑
if (!isExist(sftp, baseDir)) {
//System.out.println("創建sftp服務器路徑失敗:" + baseDir);
return false;
}
String dst = baseDir + "/" + fileName;
String src = filePath + "/" + fileName;
//System.out.println("開始上傳,本地服務器路徑:[" + src + "]目標服務器路徑:[" + dst + "]");
sftp.put(src, dst);
//System.out.println("上傳成功"+sftp.toString());
return true;
} catch (Exception e) {
//System.out.println("上傳失敗" + e);
return false;
} finally {
sftpChannel.closeChannel();
}
}
/**
* 判斷文件夾是否存在 true 目錄創建成功,false 目錄創建失敗
*
* @param sftp
* @param filePath 文件夾路徑
* @return
*/
public static boolean isExist(ChannelSftp sftp, String filePath) {
String paths[] = filePath.split("\\/");
String dir = paths[0];
for (int i = 0; i < paths.length - 1; i++) {
dir = dir + "/" + paths[i + 1];
try {
sftp.cd(dir);
} catch (SftpException sException) {
if (sftp.SSH_FX_NO_SUCH_FILE == sException.id) {
try {
sftp.mkdir(dir);
} catch (SftpException e) {
e.printStackTrace();
return false;
}
}
}
}
return true;
}
}
第五步,main方法調用測試