第一步,导包
<!-- 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方法调用测试