1、jsch 挺老的工具包 jdk可以最低支持到1.6 目前最高版本0.1.55 已经多年没有更新,jsch功能其实挺强大的,只不过时间的原因,java7后的新写法 jsch都不支持 ,如果自己封装一下 也是挺好用的,毕竟他支持文件和文件流上传
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
/**
* SFTP连接工具。
* @author wanglei
* @version 1.0
*/
public class SFtpTool implements AutoCloseable {
private static final int TIME_OUT = 60000;
private Session sshSession;
private ChannelSftp sftp;
SFtpTool(final String host, final int port, final String username, final String password) {
connect(host, port, username, password);
}
/**
* 连接SFTP服务器。
* @param host 服务器ip
* @param port 端口
* @param username 鉴权用户名
* @param password 密码
*/
private void connect(final String host, final int port, final String username, final String password) {
try {
final JSch jsch = new JSch();
sshSession = jsch.getSession(username, host, port);
sshSession.setTimeout(TIME_OUT);
sshSession.setPassword(password);
final Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
final Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
} catch (final JSchException e) {
throw new BusinessException(String.format("连接到远程SFTP服务器失败,主机名是:%s", host), e);
}
}
/**
* 上传文件。
*
* @param directory 文件要上传的目录。
* @param file 要上传的文件
*/
public void upload(final String directory, final File file) {
//文件名称
final String fileName = file.getName();
try (final FileInputStream io = new FileInputStream(file)) {
sftp.cd(directory);
sftp.put(io, fileName);
} catch (final SftpException e) {
throw new BusinessException(String.format("SFTP连接异常,文件目录是:%s", directory), e);
} catch (final IOException e) {
throw new BusinessException(String.format("文件写读异常,文件名是:%s", fileName), e);
}
}
@Override
public void close() {
if (sftp != null) {
sftp.disconnect();
}
if (sshSession != null) {
sshSession.disconnect();
}
}
public static SFtpToolBuilder builder() {
return new SFtpToolBuilder();
}
/**
* SFtpToolBuilder.
*/
public static class SFtpToolBuilder {
private String username;
private String password;
private int port;
private String host;
/**
* 设置sftp用户名。
* @param username 鉴权用户名
* @return SFtpToolBuilder
*/
public SFtpToolBuilder username(final String username) {
this.username = username;
return this;
}
/**
* 设置sftp密码。
* @param password 鉴权密码
* @return SFtpToolBuilder
*/
public SFtpToolBuilder password(final String password) {
this.password = password;
return this;
}
/**
* 设置服务器IP。
* @param host 服务器IP
* @return SFtpToolBuilder
*/
public SFtpToolBuilder host(final String host) {
this.host = host;
return this;
}
/**
* 设置sftp端口。
* @param port 端口
* @return SFtpToolBuilder
*/
public SFtpToolBuilder port(final int port) {
this.port = port;
return this;
}
/**
* 构造 SFtpTool。
* @return SFtpTool
*/
public SFtpTool build() {
return new SFtpTool(this.host, this.port, this.username, this.password);
}
}
}
实际使用
try (final SFtpTool sFtpTool =
SFtpTool.builder().username("x").password("x").host("x").port(x).build()) {
sFtpTool.upload("remote", file);
}
2、ssh-j新秀工具包 最低支持java8 搭配try-with-resource 代码量很少 不支持文件流上传,原因嘛 实际的上传方法进行了一系列的判断 是不是文件 、是不是文件夹 我觉得暂时不支持 ,以后应该会支持的,只不过要改动一下底层的逻辑
原生使用也是很方便的
try (final SSHClient sshClient = new SSHClient()) {
sshClient.addHostKeyVerifier(new PromiscuousVerifier());
sshClient.connect("192.168.31.202", 22);
sshClient.authPassword("root", "root");
try (final SFTPClient sftpClient = sshClient.newSFTPClient()) {
sftpClient.ls("/home/root/").forEach(System.out::println);
}
}
那我们如果想业务分离就需要封装一下(样例,不做NPE等判断)
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
/**
* sftpClient 工具类。
* @author wanglei
* @version 1.0
*/
public class SSHJSFtpClient implements AutoCloseable {
private SSHClient sshClient = null;
private SFTPClient sftpClient = null;
public SSHJSFtpClient(String host, int port, String username, String password) throws IOException {
sshClient = new SSHClient();
sshClient.addHostKeyVerifier(new PromiscuousVerifier());
sshClient.connect(host, port);
sshClient.authPassword(username, password);
}
public SFTPClient getSftpClient() throws IOException {
if (sftpClient != null) {
return sftpClient;
}
sftpClient = sshClient.newSFTPClient();
return sftpClient;
}
@Override
public void close() throws Exception {
IOUtils.close(sftpClient, sshClient);
}
}
实际调用
try (final SSHJSFtpClient sftpClient = new SSHJSFtpClient("192.168.31.202", 22, "root", "root"))
{
sftpClient.getSftpClient().ls("/home/root/").forEach(System.out::println);
}
3、apache的commons VFS 底层也是jsch 不讨论了