依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.5</version>
</dependency>
yml
ftp:
# enableConfig: false表示配置都使用默认配置
# enableConfig: true
host: 192.168.52.44
port: 21
username: ftpuser
password: 123456
basePath: /home/ftp
pool:
#池对象耗尽之后是否阻塞
blockWhenExhausted: true
#最大数
maxTotal: 8
#最大空闲
maxIdle: 8
#最小空闲
minIdle: 0
#最大等待时间
maxWait: 1000
#空闲验证
testWhileIdle: true
FtpClientPoolFactory
@Log4j2
@Configuration
public class FtpClientPoolFactory implements PooledObjectFactory<FTPClient> {
@Value("${ftp.host}")
private String ftpHost;
@Value("${ftp.port}")
private Integer ftpPort;
@Value("${ftp.username}")
private String ftpUsername;
@Value("${ftp.password}")
private String ftpPassword;
@Override
public void activateObject(PooledObject<FTPClient> pooledObject) throws Exception {
}
@Override
public void destroyObject(PooledObject<FTPClient> pooledObject){
FTPClient object = pooledObject.getObject();
if(object!=null && object.isConnected()){
try {
object.logout();
} catch (IOException e) {
}finally {
try {
object.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public PooledObject<FTPClient> makeObject() throws Exception {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(ftpHost, ftpPort);
ftpClient.login(ftpUsername, ftpPassword);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
ftpClient.disconnect();
throw new RuntimeException("未连接到FTP,用户名或密码错误。");
}
return new DefaultPooledObject<>(ftpClient);
}
@Override
public void passivateObject(PooledObject<FTPClient> pooledObject) throws Exception {
}
@Override
public boolean validateObject(PooledObject<FTPClient> pooledObject) {
FTPClient object = pooledObject.getObject();
try {
return object!=null && object.isConnected() && object.sendNoOp();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
FtpClientPool
@Component
public class FtpClientPool {
private GenericObjectPool<FTPClient> pool;
@Value("${ftp.enableConfig}")
private Boolean enableConfig;
@Value("${ftp.pool.blockWhenExhausted}")
private Boolean blockWhenExhausted;
@Value("${ftp.pool.maxTotal}")
private Integer maxTotal;
@Value("${ftp.pool.maxIdle}")
private Integer maxIdle;
@Value("${ftp.pool.minIdle}")
private Integer minIdle;
@Value("${ftp.pool.maxWait}")
private Integer maxWait;
@Value("${ftp.pool.testWhileIdle}")
private Boolean testWhileIdle;
public FtpClientPool(PooledObjectFactory<FTPClient> ftpClientPoolFactory) {
if(enableConfig==null || !enableConfig){
pool= new GenericObjectPool<>(ftpClientPoolFactory);
return;
}
GenericObjectPoolConfig<FTPClient> poolConfig=new GenericObjectPoolConfig<>();
poolConfig.setBlockWhenExhausted(blockWhenExhausted);
poolConfig.setMaxWaitMillis(maxWait);
poolConfig.setMinIdle(minIdle);
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMaxTotal(maxTotal);
poolConfig.setTestOnBorrow(false);
poolConfig.setTestOnReturn(false);
poolConfig.setTestOnCreate(false);
poolConfig.setTestWhileIdle(testWhileIdle);
pool=new GenericObjectPool<>(ftpClientPoolFactory,poolConfig);
}
public FTPClient borrowObject(){
try {
return pool.borrowObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void returnObject(FTPClient obj) {
pool.returnObject(obj);
}
}
使用
@Autowired
private FtpClientPool ftpClientPool;
@GetMapping("/upload")
public void upload(){
FTPClient ftpClient = ftpClientPool.borrowObject();
ftpClientPool.returnObject(ftpClient);
}