前言
FTPClient经常销毁和重新生成会很耗资源,因此需要创建ftp连接池,使用完ftp连接后归还给连接池。
一、引入依赖
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
二、线程池实现
1、配置类
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "ftp.client")
@Component
@Data
public class FtpPoolConfig extends GenericObjectPoolConfig {
private String host;
private int port = 21;
private String username;
private String password;
private String passiveMode;
private String encoding;
private int clientTimeout;
private int transferFileType;
}
2、配置文件
ftp.client.host=172.16.10.151
ftp.client.port=21
ftp.client.username=root
ftp.client.password=password123
ftp.client.encoding=utf-8
ftp.client.passiveMode=true
ftp.client.connectTimeout=30000
ftp.client.transferFileType=2
3、连接池
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
@Slf4j
public class FtpClientFactory implements PooledObjectFactory<FTPClient> {
@Autowired
private FtpPoolConfig config;
@Override
public void destroyObject(PooledObject<FTPClient> pool) throws Exception {
FTPClient ftpClient = pool.getObject();
if (ftpClient != null) {
try {
ftpClient.disconnect();
log.debug("销毁ftp连接");
} catch (Exception e) {
log.error("销毁ftpClient异常,error:", e.getMessage());
}
}
}
@Override
public PooledObject<FTPClient> makeObject() throws Exception {
FTPClient ftpClient = new FTPClient();
ftpClient.setConnectTimeout(config.getClientTimeout());
ftpClient.connect(config.getHost(), config.getPort());
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
return null;
}
boolean success = false;
if (StringUtils.isBlank(config.getUsername())) {
success = ftpClient.login("anonymous", "anonymous");
} else {
success = ftpClient.login(config.getUsername(), config.getPassword());
}
if (!success) {
return null;
}
ftpClient.setFileType(config.getTransferFileType());
ftpClient.setBufferSize(1024);
ftpClient.setControlEncoding(config.getEncoding());
if (config.getPassiveMode() != null && config.getPassiveMode().equals("true")) {
ftpClient.enterLocalPassiveMode();
}
log.debug("创建ftp连接");
return new DefaultPooledObject<>(ftpClient);
}
@Override
public boolean validateObject(PooledObject<FTPClient> pool) {
FTPClient ftpClient = pool.getObject();
try {
return ftpClient != null && ftpClient.sendNoOp();
} catch (IOException e) {
return false;
}
}
@Override
public void passivateObject(PooledObject<FTPClient> p) throws Exception {
}
@Override
public void activateObject(PooledObject<FTPClient> pool) throws Exception {
}
}
4、操作接口
import org.apache.commons.net.ftp.FTPClient;
public interface FtpPoolService {
/**
* 获取ftpClient
*/
FTPClient borrowObject() throws Exception;
/**
* 归还ftpClient
*/
void returnObject(FTPClient ftpClient) throws Exception;
}
5、操作实现类
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class FtpPoolServiceImpl implements FtpPoolService {
private GenericObjectPool<FTPClient> pool;
@Autowired
private FtpPoolConfig config;
@Autowired
private FtpClientFactory factory;
/**
* 初始化pool
*/
@PostConstruct
private void initPool() {
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
this.pool = new GenericObjectPool<FTPClient>(this.factory, this.config);
}
/**
* 获取ftpClient
*/
@Override
public FTPClient borrowObject() throws Exception {
if (this.pool != null) {
return this.pool.borrowObject();
}
return null;
}
/**
* 归还 ftpClient
*/
@Override
public void returnObject(FTPClient ftpClient) {
if (this.pool != null && ftpClient != null) {
this.pool.returnObject(ftpClient);
}
}
}