
最近项目中经常用的jsch来进行文件上传下载,在业务量大的时候,每次都去获取sftp连接很消耗资源,后面就想着使用连接池来解决。
简述1)jsch是ssh2的一个纯Java实现。它允许你连接到一个sshd服务器,使用端口转发、X11转发、文件传输等。
2)SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。
3)ftp协议通常是用来在两个服务器之间传输文件的,但是它本质上是不安全的。
4)SFTP可以理解为SSH + FTP,也就是安全的网络文件传输协议。
com.jcraft
jsch
0.1.55
org.apache.commons
commons-pool2
application.yml配置文件
sftp:
#服务器ip
host: 192.168.159.135
#ssh端口
port: 22
#用户名
username: YB001
#密码
password: 123456
#连接池参数
pool:
#对象池中管理的最多对象个数。默认值是8
max-total: 10
#对象池中最大的空闲对象个数。默认值是8
max-idle: 10
#对象池中最小的空闲对象个数。默认值是0
min-idle: 5
配置类
@Data public class SftpPoolProperties extends GenericObjectPoolConfig连接池实现{ @Value("${sftp.pool.max-total}") private int maxTotal = DEFAULT_MAX_TOTAL; @Value("${sftp.pool.max-idle}") private int maxIdle = DEFAULT_MAX_IDLE; @Value("${sftp.pool.min-idle}") private int minIdle = DEFAULT_MIN_IDLE; public SftpPoolProperties() { super.setMaxIdle(maxIdle); super.setMaxTotal(maxTotal); super.setMinIdle(minIdle); } } @Data public class SftpProperties { @Value("${sftp.host}") private String host; @Value("${sftp.port}") private int port; @Value("${sftp.username}") private String username; @Value("${sftp.password}") private String password; }
@Data
public class SftpPool {
private GenericObjectPool pool;
public SftpPool(SftpFactory factory, SftpPoolProperties sftpPoolProperties) {
this.pool = new GenericObjectPool<>(factory, sftpPoolProperties);
}
public ChannelSftp borrowObject() throws Exception {
return pool.borrowObject();
}
public void returnObject(ChannelSftp channelSftp) {
if (channelSftp != null) {
pool.returnObject(channelSftp);
}
}
}
public class SftpFactory extends basePooledObjectFactory {
private SftpProperties properties;
public SftpFactory(SftpProperties properties) {
this.properties = properties;
}
@Override
public ChannelSftp create() throws JSchException {
JSch jsch = new JSch();
Session sshSession = jsch.getSession(properties.getUsername(), properties.getHost(), properties.getPort());
sshSession.setPassword(properties.getPassword());
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp");
channel.connect();
return channel;
}
@Override
public PooledObject wrap(ChannelSftp channelSftp) {
return new DefaultPooledObject<>(channelSftp);
}
@Override
public void destroyObject(PooledObject p) {
ChannelSftp channelSftp = p.getObject();
channelSftp.disconnect();
}
@Override
public void activateObject(PooledObject p) throws Exception {
ChannelSftp channelSftp = p.getObject();
if(!channelSftp.isConnected()){
channelSftp.connect();
}
}
public SftpProperties getProperties() {
return properties;
}
public void setProperties(SftpProperties properties) {
this.properties = properties;
}
}
Sftp工具类
@Data
public class SftpUtil {
private final SftpPool pool;
public SftpUtil(SftpPool pool) {
this.pool = pool;
}
public InputStream download(String dir, String name) throws Exception {
ChannelSftp sftp = pool.borrowObject();
try {
sftp.cd(dir);
return sftp.get(name);
} finally {
pool.returnObject(sftp);
}
}
public void upload(String dir, String name, InputStream in) throws Exception {
ChannelSftp sftp = pool.borrowObject();
try {
mkdirs(sftp, dir);
sftp.cd(dir);
sftp.put(in, name);
} finally {
pool.returnObject(sftp);
}
}
public void delete(String dir, String name) throws Exception {
ChannelSftp sftp = pool.borrowObject();
try {
sftp.cd(dir);
sftp.rm(name);
} finally {
pool.returnObject(sftp);
}
}
private void mkdirs(ChannelSftp sftp, String dir) throws SftpException {
String[] folders = dir.split("/");
sftp.cd("/");
for (String folder : folders) {
if (folder.length() > 0) {
try {
sftp.cd(folder);
} catch (Exception e) {
sftp.mkdir(folder);
sftp.cd(folder);
}
}
}
}
}
配置成Bean
@Configuration
public class SftpConfig {
@Bean
public SftpProperties sftpProperties() {
return new SftpProperties();
}
@Bean
public SftpPoolProperties sftpPoolProperties(){
return new SftpPoolProperties();
}
@Bean
public SftpFactory sftpFactory(SftpProperties sftpProperties) {
return new SftpFactory(sftpProperties);
}
@Bean
public SftpPool sftpPool(SftpFactory sftpFactory, SftpPoolProperties sftpPoolProperties) {
return new SftpPool(sftpFactory, sftpPoolProperties);
}
}
测试
项目地址:https://github.com/fengfangithub/study-sftp.git
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)