一、导入依赖
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
二、sftp.properties配置信息文件
sftp.client.protocol=sftp
sftp.client.host=localhost
sftp.client.port=22
sftp.client.username=kungfupanda
sftp.client.password=xxxxx
sftp.client.root=/Users/kungfupanda
sftp.client.privateKey=
sftp.client.passphrase=
sftp.client.sessionStrictHostKeyChecking=no
sftp.client.sessionConnectTimeout=15000
sftp.client.channelConnectedTimeout=15000
sftp.client.localPath=./_files
按照第一篇所说,创建sftp server。这里是连接到本地mac的sftp server,而嵌入式的sftp server一般用来测试。
三、SftpProperties配置类
@Data
@Component
@PropertySource(value = "classpath:sftp.properties")
public class SftpProperties {
@Value("${sftp.client.host}")
private String host;
@Value("${sftp.client.port}")
private Integer port;
@Value("${sftp.client.protocol}")
private String protocol;
@Value("${sftp.client.username}")
private String username;
@Value("${sftp.client.password}")
private String password;
@Value("${sftp.client.root}")
private String root;
@Value("${sftp.client.privateKey}")
private String privateKey;
@Value("${sftp.client.passphrase}")
private String passphrase;
@Value("${sftp.client.sessionStrictHostKeyChecking}")
private String sessionStrictHostKeyChecking;
@Value("${sftp.client.sessionConnectTimeout}")
private Integer sessionConnectTimeout;
@Value("${sftp.client.channelConnectedTimeout}")
private Integer channelConnectedTimeout;
@Value("${sftp.client.localPath}")
private String localPath;
}
这里将外部配置信息加载到类中。
四、SftpUtils类
@Slf4j
@Component
public class SftpUtils {
// set first login prompt : ask, yes, no
private static final String STRICT_HOST_KEY_CHECKING = "StrictHostKeyChecking";
@Autowired
private SftpProperties sftpProperties;
public File downloadFile(String src, String dst, int mode) throws JSchException {
ChannelSftp sftp = this.createSftp();
try {
sftp.cd(sftpProperties.getRoot());
log.info("Change path to " + sftpProperties.getRoot());
File file = new File(dst);
sftp.get(src, dst, new CddSftpProgressMonitor(), mode);
log.info("Download file success. TargetPath: " + src);
return file;
} catch (SftpException e) {
log.error("SftpException:", e);
throw new BatchProcessingException("SftpException");
} catch (Exception e) {
log.error("Download file failure. TargetPath: " + src, e);
throw new BatchProcessingException("Download File failure");
} finally {
this.disconnect(sftp);
}
}
public ChannelSftp createSftp() throws JSchException {
JSch jsch = new JSch();
Boolean boo = StringUtils.isNotBlank(sftpProperties.getPrivateKey());
if (boo) {
if (StringUtils.isNotBlank(sftpProperties.getPassphrase())) {
jsch.addIdentity(sftpProperties.getPrivateKey(), sftpProperties.getPassphrase());
} else {
jsch.addIdentity(sftpProperties.getPrivateKey());
}
}
log.info("Try to connect sftp[" + sftpProperties.getUsername() + "@" + sftpProperties.getHost() + "], use password[" + sftpProperties.getPassword() + "]");
Session session = createSession(jsch, sftpProperties.getHost(), sftpProperties.getUsername(), sftpProperties.getPort());
if (!boo) {
session.setPassword(sftpProperties.getPassword());
}
session.connect(sftpProperties.getSessionConnectTimeout());
log.info("Session connected to [" + sftpProperties.getHost() + "]");
Channel channel = session.openChannel(sftpProperties.getProtocol());
channel.connect(sftpProperties.getChannelConnectedTimeout());
log.info("Channel created to [" + sftpProperties.getHost() + "]");
return (ChannelSftp) channel;
}
private Session createSession(JSch jsch, String host, String username, Integer port) throws JSchException {
Session session = port <= 0 ? jsch.getSession(username, host) : jsch.getSession(username, host, port);
if (session == null) {
throw new BatchProcessingException(host + " session is null");
}
session.setConfig(STRICT_HOST_KEY_CHECKING, sftpProperties.getSessionStrictHostKeyChecking());
return session;
}
private void disconnect(ChannelSftp sftp) {
try {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
} else if (sftp.isClosed()) {
log.info("sftp is closed already");
}
if (sftp.getSession() != null) {
sftp.getSession().disconnect();
}
}
} catch (JSchException e) {
log.error("disconnect failure", e);
}
}
}
jsch是通过ChannelSftp来进行具体操作的,比如上传下载等。
五、SftpProgressMonitor监控类
@Slf4j
public class CddSftpProgressMonitor implements SftpProgressMonitor {
private long count = 0; //当前接收的总字节数
private long max = 0; //最终文件大小
private long percent = -1; //进度
@Override
public boolean count(long count) {
this.count += count;
if (percent >= this.count * 100 / max) {
return true;
}
percent = this.count * 100 / max;
log.info("Completed " + this.count + "(" + percent + "%) out of " + max + ".");
return true;
}
@Override
public void init(int op, String src, String dest, long max) {
if (op == SftpProgressMonitor.PUT) {
log.info("Upload file begin.");
} else {
log.info("Download file begin.");
}
this.max = max;
this.count = 0;
this.percent = -1;
}
@Override
public void end() {
log.info("Transferring done.");
}
}
通过实现SftpProgressMonitor来监控文件下载进度等。