addObject();
}
}
@Override
public FTPClient borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
// 从连接池拿出一个连接,连接池中连接对象减一
FTPClient client = pool.take();
if (client == null) {
throw new RuntimeException("从连接池获取连接失败!");
}
return client;
}
@Override
public void returnObject(FTPClient obj) throws Exception {
if (obj != null) {
try {
// 归还连接
factory.passivateObject(obj);
// 将连接还给队列
pool.offer(obj);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 移除无效的客户端
* @param obj
* @throws Exception
*/
@Override
public void invalidateObject(FTPClient obj) throws Exception {
pool.remove(obj);
}
@Override
public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
this.pool.offer(factory.makeObject());
}
@Override
public int getNumIdle() throws UnsupportedOperationException {
return 0;
}
@Override
public int getNumActive() throws UnsupportedOperationException {
return 0;
}
@Override
public void clear() throws Exception, UnsupportedOperationException {
pool.clear();
}
@Override
public void close() throws Exception {
while(pool.iterator().hasNext()){
FTPClient client = pool.take();
factory.destroyObject(client);
}
}
@Override
public void setFactory(PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
}
/**
* 连接池对象销毁前关闭连接
*/
@Override
protected void finalize() throws Throwable {
super.finalize();
close();
}
@Override
public void afterPropertiesSet() throws Exception {
initPool();
}
}
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool.PoolableObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class FtpClientFactory implements PoolableObjectFactory {
@Autowired
private FTPConfig ftpConfig;
@Override
public FTPClient makeObject() throws Exception {
FTPClient ftpClient = new FTPClient();
ftpClient.setConnectTimeout(1000);
try {
ftpClient.connect(ftpConfig.getIp(), ftpConfig.getPort());
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new RuntimeException("ftpClient连接失败!");
}
boolean result = ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword());
if (!result) {
throw new RuntimeException("ftpClient登陆失败!");
}
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
ftpClient.setControlEncoding("UTF-8");
}
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setBufferSize(1024);
ftpClient.enterLocalPassiveMode(); //ftp被动连接模式
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new RuntimeException("ftpClient连接失败!");
}
} catch (IOException e) {
ftpClient.disconnect();
e.printStackTrace();
} catch (Exception e) {
ftpClient.disconnect();
e.printStackTrace();
}
return ftpClient;
}
/**
* 关闭连接
* @param obj
* @throws Exception
*/
@Override
public void destroyObject(FTPClient obj) throws Exception {
try {
if (obj != null && obj.isConnected()) {
obj.logout();
}
} catch (IOException io) {
io.printStackTrace();
} finally {
// 注意,一定要在finally代码中断开连接,否则会导致占用ftp连接情况
try {
obj.disconnect();
} catch (IOException io) {
io.printStackTrace();
}
}
}
@Override
public boolean validateObject(FTPClient obj) {
try {
return obj.sendNoOp();
} catch (IOException e) {
throw new RuntimeException("Failed to validate client: " + e, e);
}
}
@Override
public void activateObject(FTPClient obj) throws Exception {
}
/**
* 归还连接
* @param obj
* @throws Exception
*/
@Override
public void passivateObject(FTPClient obj) throws Exception {
try {
if (obj != null && obj.isConnected()) {
obj.completePendingCommand();
obj.changeWorkingDirectory("/");
}
} catch (IOException io) {
io.printStackTrace();
}
}
}
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:application-ftp.yml")
@ConfigurationProperties(prefix = "ftp")
@Data
public class FTPConfig {
private String ip;
private int port;
private String username;
private String password;
}
以上就是FTPClient连接池全部实现。
但是有个问题,测试环境用的是XLight FTP Server,用同一个账号连接,最多只能同时连5个,希望知道的大佬告知怎么设置。