原文: https://blog.csdn.net/qq_35433926/article/details/91880345
springboot2.1.3配置sftp,自定义sftp连接池
项目地址
项目地址:https://gitee.com/xuelingkang/spring-boot-demo
完整配置参考com.example.ftp包
maven:
<!-- sftp --> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency> <!-- commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.1</version> </dependency>
application.yml配置
sftp: host: server02 # 服务器ip port: 22 # ssh端口 username: demofile # 用户名 password: demo # 密码 # 连接池参数 pool: max-total: 10 max-idle: 10 min-idle: 5
SftpProperties
package com.example.ftp; import com.jcraft.jsch.ChannelSftp; import lombok.Data; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.boot.context.properties.ConfigurationProperties; @Data @ConfigurationProperties(prefix = "sftp") public class SftpProperties { private String host; private int port = 22; private String username = "root"; private String password = "root"; private Pool pool = new Pool(); public static class Pool extends GenericObjectPoolConfig<ChannelSftp> { private int maxTotal = DEFAULT_MAX_TOTAL; private int maxIdle = DEFAULT_MAX_IDLE; private int minIdle = DEFAULT_MIN_IDLE; public Pool() { super(); } @Override public int getMaxTotal() { return maxTotal; } @Override public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; } @Override public int getMaxIdle() { return maxIdle; } @Override public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } @Override public int getMinIdle() { return minIdle; } @Override public void setMinIdle(int minIdle) { this.minIdle = minIdle; } } }
sftp连接工厂
package com.example.ftp; import com.example.exception.ProjectException; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.impl.DefaultPooledObject; import java.util.Properties; @Data @Slf4j public class SftpFactory extends BasePooledObjectFactory<ChannelSftp> { private SftpProperties properties; public SftpFactory(SftpProperties properties) { this.properties = properties; } @Override public ChannelSftp create() { try { 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; } catch (JSchException e) { throw new ProjectException("连接sfpt失败", e); } } @Override public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) { return new DefaultPooledObject<>(channelSftp); } // 销毁对象 @Override public void destroyObject(PooledObject<ChannelSftp> p) { ChannelSftp channelSftp = p.getObject(); channelSftp.disconnect(); } }
sftp连接池
package com.example.ftp; import com.example.exception.ProjectException; import com.jcraft.jsch.ChannelSftp; import lombok.Data; import org.apache.commons.pool2.impl.GenericObjectPool; @Data public class SftpPool { private GenericObjectPool<ChannelSftp> pool; public SftpPool(SftpFactory factory) { this.pool = new GenericObjectPool<>(factory, factory.getProperties().getPool()); } /** * 获取一个sftp连接对象 * @return sftp连接对象 */ public ChannelSftp borrowObject() { try { return pool.borrowObject(); } catch (Exception e) { throw new ProjectException("获取ftp连接失败", e); } } /** * 归还一个sftp连接对象 * @param channelSftp sftp连接对象 */ public void returnObject(ChannelSftp channelSftp) { if (channelSftp!=null) { pool.returnObject(channelSftp); } } }
sftp辅助类
package com.example.ftp; import com.example.exception.ProjectException; import com.example.util.ByteUtil; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.SftpException; import java.io.InputStream; // sftp辅助类 public class SftpHelper { private SftpPool pool; public SftpHelper(SftpPool pool) { this.pool = pool; } /** * 下载文件 * @param dir 远程目录 * @param name 远程文件名 * @return 文件字节数组 */ public byte[] download(String dir, String name) { ChannelSftp sftp = pool.borrowObject(); try { sftp.cd(dir); InputStream in = sftp.get(name); return ByteUtil.inputStreamToByteArray(in); } catch (SftpException e) { throw new ProjectException("sftp下载文件出错", e); } finally { pool.returnObject(sftp); } } /** * 上传文件 * @param dir 远程目录 * @param name 远程文件名 * @param in 输入流 */ public void upload(String dir, String name, InputStream in) { ChannelSftp sftp = pool.borrowObject(); try { mkdirs(sftp, dir); sftp.cd(dir); sftp.put(in, name); } catch (SftpException e) { throw new ProjectException("sftp上传文件出错", e); } finally { pool.returnObject(sftp); } } /** * 删除文件 * @param dir 远程目录 * @param name 远程文件名 */ public void delete(String dir, String name) { ChannelSftp sftp = pool.borrowObject(); try { sftp.cd(dir); sftp.rm(name); } catch (SftpException e) { throw new ProjectException("sftp删除文件出错", e); } finally { pool.returnObject(sftp); } } /** * 递归创建多级目录 * @param dir 多级目录 */ private void mkdirs(ChannelSftp sftp, String dir) { String[] folders = dir.split("/"); try { sftp.cd("/"); for (String folder: folders) { if (folder.length()>0) { try { sftp.cd(folder); } catch (Exception e) { sftp.mkdir(folder); sftp.cd(folder); } } } } catch (SftpException e) { throw new ProjectException("sftp创建目录出错", e); } } }
主配置类
package com.example.config; import com.example.ftp.SftpFactory; import com.example.ftp.SftpHelper; import com.example.ftp.SftpPool; import com.example.ftp.SftpProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; // ftp配置 @Configuration @EnableConfigurationProperties(SftpProperties.class) public class SftpConfig { // 工厂 @Bean public SftpFactory sftpFactory(SftpProperties properties) { return new SftpFactory(properties); } // 连接池 @Bean public SftpPool sftpPool(SftpFactory sftpFactory) { return new SftpPool(sftpFactory); } // 辅助类 @Bean public SftpHelper sftpHelper(SftpPool sftpPool) { return new SftpHelper(sftpPool); } }
使用方法
@Autowired
private SftpHelper sftpHelper;
注入辅助类,直接调用方法即可。