最近在对接一个接口,需要通过安全边界进入到内网,进入边界需要将请求信息打包成文本文件上传到ftp服务器。上传文件每次都需要连接,登陆,为了提高效率,想到了DBCP数据库连接池是基于common-pool实现,查阅了相关资料,实现了一个简单的FTPPool。
相关代码如下:
Pool对象,抽象类,通用对象池
package com.wl.ftp;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class Pool<T> {
private final GenericObjectPool<T> internalPool;
private Logger logger = LoggerFactory.getLogger(getClass());
public Pool(GenericObjectPool.Config poolConfig, PoolableObjectFactory<T> factory) {
this.internalPool = new GenericObjectPool<>(factory, poolConfig);
}
/**
* 获取资源
* @return
*/
public T getResource() {
try {
return this.internalPool.borrowObject();
} catch (Exception e) {
logger.error("getResource exception", e);
return null;
}
}
/**
* 归还资源
* @param resource
*/
public void returnResource(T resource) {
try {
this.internalPool.returnObject(resource);
} catch (Exception e) {
logger.error("returnResource exception", e);
}
}
/**
* 销毁池子
*/
public void destroy() {
try {
this.internalPool.close();
} catch (Exception e) {
logger.error("destroy exception", e);
}
}
}
FTPPool工厂,用于生产,校验,销毁对象。
package com.wl.ftp;
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.BasePoolableObjectFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class FTPPoolAbleObjectFactory extends BasePoolableObjectFactory<FTPClient> {
private FTPClientConfigure ftpClientConfigure;
private static Logger logger = LoggerFactory.getLogger(FTPPoolAbleObjectFactory.class);
public FTPPoolAbleObjectFactory(FTPClientConfigure ftpClientConfigure) {
this.ftpClientConfigure = ftpClientConfigure;
}
@Override
public FTPClient makeObject() throws Exception {
FTPClient ftpClient = new FTPClient();
ftpClient.setConnectTimeout(ftpClientConfigure.getClientTimeout());
ftpClient.connect(ftpClientConfigure.getHost(), ftpClientConfigure.getPort());
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
logger.error("FTPServer refused connection");
return null;
}
boolean result = ftpClient.login(ftpClientConfigure.getUsername(), ftpClientConfigure.getPassword());
if (!result) {
throw new RuntimeException("ftpClient登陆失败");
}
ftpClient.setBufferSize(1024);
ftpClient.setControlEncoding(ftpClientConfigure.getEncoding());
ftpClient.setControlEncoding("UTF-8");
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
if (ftpClientConfigure.getPassiveMode()) {
ftpClient.enterLocalPassiveMode();
}
return ftpClient;
}
@Override
public void destroyObject(FTPClient ftpClient) throws Exception {
try {
if (ftpClient != null && ftpClient.isConnected()) {
ftpClient.logout();
}
} catch (IOException io) {
logger.error("destory object exception", io);
} finally {
// 注意,一定要在finally代码中断开连接,否则会导致占用ftp连接情况
try {
if (ftpClient != null) {
ftpClient.disconnect();
}
} catch (Exception io) {
logger.error("destory object exception", io);
}
}
}
@Override
public boolean validateObject(FTPClient ftpClient) {
try {
return ftpClient.sendNoOp();//
} catch (IOException e) {
logger.error("Failed to validate client:", e);
return false;
}
}
}
FTPPool对象
package com.wl.ftp;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
public class FTPPool extends Pool<FTPClient> {
public FTPPool(Config poolConfig, FTPClientConfigure ftpClientConfigure) {
this(poolConfig, new FTPPoolAbleObjectFactory(ftpClientConfigure));
}
public FTPPool(Config poolConfig, PoolableObjectFactory<FTPClient> factory) {
super(poolConfig, factory);
}
}
FTPClient 配置信息
package com.wl.ftp;
/**
* FTPClient配置类
*/
public class FTPClientConfigure {
private String host;
private int port;
private String username;
private String password;
private boolean passiveMode;
private String encoding;
private int clientTimeout;
private int transferFileType;
private int retryTimes;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean getPassiveMode() {
return passiveMode;
}
public void setPassiveMode(boolean passiveMode) {
this.passiveMode = passiveMode;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public int getClientTimeout() {
return clientTimeout;
}
public void setClientTimeout(int clientTimeout) {
this.clientTimeout = clientTimeout;
}
public int getRetryTimes() {
return retryTimes;
}
public void setRetryTimes(int retryTimes) {
this.retryTimes = retryTimes;
}
public int getTransferFileType() {
return transferFileType;
}
public void setTransferFileType(int transferFileType) {
this.transferFileType = transferFileType;
}
}
部分代码参考:1、http://shensy.iteye.com/blog/1569411
2、http://blog.csdn.net/suifeng3051/article/details/48969679
感谢两位!
另附源码地址https://git.oschina.net/fshuqing/ftp-pool