博客详情

spring中使用ftp连接池(ftpClientPool) (原创)

作者: 朝如青丝暮成雪
发布时间:2018-06-23 07:54:08  文章分类:java编程   阅读(1886)  评论(0)
如题,我们在一些项目中可能会涉及到ftp上传、下载客户资料、附件。但是若每次上传或下载时都去创建一次ftp连接,上传(  下载)一个文件再关闭,则太耗费连接资源,这时候可以考虑使用连接池(就如同我们需要jdbc数据库连接池的道理一样)


笔者参考了网上的一些示例、技术文章,以及现有的apache commons-pool组件的代码等,自己封装了一套还算是比较完整的代码(此连接池底层依赖apache的commons-net和commons-pool2 组件) 。

此项目笔者已发布到github上了,项目地址:

https://github.com/jellyflu/ftpClientPool   (对源码感兴趣的同学,请移步github哦 ~)

其实项目代码也不复杂,就是对apache ftp做了薄层的封装,总共才几个类,一千行代码不到。


FtpPoolConfig.java  继承自GenericObjectPoolConfig ,封装ftp的一些连接参数等。

package com.tingcream.ftpClientPool.config;  
  
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;  
  
/** 
 * ftp配置参数对象   继承自GenericObjectPoolConfig  
 *  
 * @author jelly 
 * 
 */  
public class FtpPoolConfig extends   GenericObjectPoolConfig{  
      
    private  String host;//主机名  
    private  int port=21;//端口  
    private  String username;//用户名  
    private   String password;//密码  
      
    private int  connectTimeOut=5000;//ftp 连接超时时间 毫秒  
    private String  controlEncoding="utf-8";  
    private int  bufferSize  =1024;//缓冲区大小  
    private  int  fileType =2  ;//  传输数据格式   2表binary二进制数据  
    private  int  dataTimeout=  120000;  
    private   boolean  useEPSVwithIPv4 =false;  
    private  boolean  passiveMode =true;//是否启用被动模式  
      
     
    public int getConnectTimeOut() {  
        return connectTimeOut;  
    }  
    public void setConnectTimeOut(int connectTimeOut) {  
        this.connectTimeOut = connectTimeOut;  
    }  
    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 String getControlEncoding() {  
        return controlEncoding;  
    }  
    public void setControlEncoding(String controlEncoding) {  
        this.controlEncoding = controlEncoding;  
    }  
    public int getBufferSize() {  
        return bufferSize;  
    }  
    public void setBufferSize(int bufferSize) {  
        this.bufferSize = bufferSize;  
    }  
       
    public int getFileType() {  
        return fileType;  
    }  
    public void setFileType(int fileType) {  
        this.fileType = fileType;  
    }  
    public int getDataTimeout() {  
        return dataTimeout;  
    }  
    public void setDataTimeout(int dataTimeout) {  
        this.dataTimeout = dataTimeout;  
    }  
    public boolean isUseEPSVwithIPv4() {  
        return useEPSVwithIPv4;  
    }  
    public void setUseEPSVwithIPv4(boolean useEPSVwithIPv4) {  
        this.useEPSVwithIPv4 = useEPSVwithIPv4;  
    }  
    public boolean isPassiveMode() {  
        return passiveMode;  
    }  
    public void setPassiveMode(boolean passiveMode) {  
        this.passiveMode = passiveMode;  
    }  
      
      
}  

FTPClientFactory.java   ftp客户端连接创建工厂


package com.tingcream.ftpClientPool.core;  
  
import java.io.IOException;  
  
import org.apache.commons.net.ftp.FTPClient;  
import org.apache.commons.net.ftp.FTPReply;  
import org.apache.commons.pool2.BasePooledObjectFactory;  
import org.apache.commons.pool2.PooledObject;  
import org.apache.commons.pool2.impl.DefaultPooledObject;  
import org.apache.log4j.Logger;  
  
import com.tingcream.ftpClientPool.config.FtpPoolConfig;  
   
/** 
 * ftpclient 工厂 
 * @author jelly 
 * 
 */  
public class FTPClientFactory extends BasePooledObjectFactory<FTPClient> {  
      
    private static Logger logger =Logger.getLogger(FTPClientFactory.class);  
      
    private FtpPoolConfig ftpPoolConfig;  
      
       
     
    public FtpPoolConfig getFtpPoolConfig() {  
        return ftpPoolConfig;  
    }  
  
    public void setFtpPoolConfig(FtpPoolConfig ftpPoolConfig) {  
        this.ftpPoolConfig = ftpPoolConfig;  
    }  
  
    /** 
     * 新建对象 
     */  
    @Override  
    public FTPClient create() throws Exception {  
        FTPClient ftpClient = new FTPClient();  
        ftpClient.setConnectTimeout(ftpPoolConfig.getConnectTimeOut());  
        try {  
              
            logger.info("连接ftp服务器:" +ftpPoolConfig.getHost()+":"+ftpPoolConfig.getPort());  
            ftpClient.connect(ftpPoolConfig.getHost(), ftpPoolConfig.getPort());  
              
            int reply = ftpClient.getReplyCode();  
            if (!FTPReply.isPositiveCompletion(reply)) {  
                ftpClient.disconnect();  
                logger.error("FTPServer 拒绝连接");  
                return null;  
            }  
            boolean result = ftpClient.login(ftpPoolConfig.getUsername(),ftpPoolConfig.getPassword());  
            if (!result) {  
                logger.error("ftpClient登录失败!");  
                throw new Exception("ftpClient登录失败! userName:"+ ftpPoolConfig.getUsername() + ", password:"  
                        + ftpPoolConfig.getPassword());  
            }  
           
            ftpClient.setControlEncoding(ftpPoolConfig.getControlEncoding());  
            ftpClient.setBufferSize(ftpPoolConfig.getBufferSize());  
            ftpClient.setFileType(ftpPoolConfig.getFileType());  
            ftpClient.setDataTimeout(ftpPoolConfig.getDataTimeout());  
            ftpClient.setUseEPSVwithIPv4(ftpPoolConfig.isUseEPSVwithIPv4());  
            if(ftpPoolConfig.isPassiveMode()){  
                logger.info("进入ftp被动模式");  
                ftpClient.enterLocalPassiveMode();//进入被动模式  
            }  
        } catch (IOException e) {  
            logger.error("FTP连接失败:", e);  
        }  
        return ftpClient;  
    }  
  
    @Override  
    public PooledObject<FTPClient> wrap(FTPClient ftpClient) {  
        return new DefaultPooledObject<FTPClient>(ftpClient);  
    }  
  
    /** 
     * 销毁对象 
     */  
    @Override  
    public void destroyObject(PooledObject<FTPClient> p) throws Exception {  
        FTPClient ftpClient = p.getObject();  
        ftpClient.logout();  
        super.destroyObject(p);  
    }  
  
    /** 
     * 验证对象 
     */  
    @Override  
    public boolean validateObject(PooledObject<FTPClient> p) {  
        FTPClient ftpClient = p.getObject();  
        boolean connect = false;  
        try {  
            connect = ftpClient.sendNoOp();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return connect;  
    }  
      
  
    /** 
     *  No-op. 
     * 
     *  @param p ignored 
     */  
    @Override  
    public void activateObject(PooledObject<FTPClient> p) throws Exception {  
        // The default implementation is a no-op.  
    }  
  
    /** 
     *  No-op. 
     * 
     * @param p ignored 
     */  
    @Override  
    public void passivateObject(PooledObject<FTPClient> p)  
        throws Exception {  
        // The default implementation is a no-op.  
    }  
}  

FTPClientPool.java   FTP客户端连接池


package com.tingcream.ftpClientPool.core;  
   
  
import org.apache.commons.net.ftp.FTPClient;  
import org.apache.commons.pool2.impl.GenericObjectPool;  
  
/** 
 * FTP 客户端连接池 
 * @author jelly 
 * 
 */  
public class FTPClientPool {  
      
    /** 
     * ftp客户端连接池 
     */  
    private GenericObjectPool<FTPClient> pool;  
   
    /** 
     * ftp客户端工厂 
     */  
    private       FTPClientFactory clientFactory;  
      
      
     /** 
      * 构造函数中 注入一个bean 
      *  
      * @param clientFactory 
      */  
    public   FTPClientPool(  FTPClientFactory clientFactory){  
        this.clientFactory=clientFactory;  
        pool = new GenericObjectPool<FTPClient>(clientFactory, clientFactory.getFtpPoolConfig());  
         
     }  
       
      
    public FTPClientFactory getClientFactory() {  
        return clientFactory;  
    }  
  
  
    public GenericObjectPool<FTPClient> getPool() {  
        return pool;  
    }  
  
  
    /** 
     * 借  获取一个连接对象 
     * @return 
     * @throws Exception 
     */  
    public FTPClient borrowObject() throws Exception {  
          
        FTPClient  client =    pool.borrowObject();  
          
//      if(!client.sendNoOp()){  
//          //使池中的对象无效   
//           client.logout();  
//           client.disconnect();  
//           pool.invalidateObject(client);  
//           client =clientFactory.create();  
//           pool.addObject();  
//       }  
//          
        return client ;  
      
    }  
    /** 
     * 还   归还一个连接对象 
     * @param ftpClient 
     */  
    public void returnObject(FTPClient ftpClient) {  
          
        if(ftpClient!=null){  
            pool.returnObject(ftpClient);   
        }  
    }  
}  
 FTPClientHelper.java   ftp客户端辅助类



package com.tingcream.ftpClientPool.client;  
  
import java.io.IOException;  
import java.io.InputStream;  
  
import org.apache.commons.net.ftp.FTPClient;  
  
import com.tingcream.ftpClientPool.core.FTPClientPool;  
import com.tingcream.ftpClientPool.util.ByteUtil;  
  
/** 
 * ftp客户端辅助bean   
 *   
 * @author jelly 
 * 
 */  
public class FTPClientHelper {  
      
  
    private FTPClientPool  ftpClientPool;  
  
    public void setFtpClientPool(FTPClientPool ftpClientPool) {  
        this.ftpClientPool = ftpClientPool;  
    }  
      
    /** 
     * 下载 remote文件流   
     * @param remote 远程文件 
     * @return 字节数据 
     * @throws Exception 
     */  
    public   byte[] retrieveFileStream(String remote) throws Exception {  
        FTPClient client=null;  
        InputStream in =null;  
        try {  
            //  long start =System.currentTimeMillis();  
               client=  ftpClientPool.borrowObject();  
               in=client.retrieveFileStream(remote);  
            //  long end =System.currentTimeMillis();  
             // System.out.println("ftp下载耗时(毫秒):"+(end-start));  
            return   ByteUtil.inputStreamToByteArray(in);  
         }finally{  
              if (in != null) {    
                    in.close();    
                }   
            if (!client.completePendingCommand()) {    
                client.logout();    
                client.disconnect();    
                ftpClientPool.getPool().invalidateObject(client);  
            }   
            ftpClientPool.returnObject(client);  
               
        }  
    }  
      
    /** 
     * 创建目录    单个不可递归 
     * @param pathname 目录名称 
     * @return 
     * @throws Exception 
     */  
    public   boolean makeDirectory(String pathname) throws Exception {  
          
        FTPClient client=null;  
        try {  
            client= ftpClientPool.borrowObject();  
            return  client.makeDirectory(pathname);  
        }  finally{  
            ftpClientPool.returnObject(client);  
        }  
    }  
      
    /** 
     * 删除目录,单个不可递归 
     * @param pathname 
     * @return 
     * @throws IOException 
     */  
    public   boolean removeDirectory(String pathname) throws Exception {  
        FTPClient client=null;  
        try {  
            client= ftpClientPool.borrowObject();  
            return  client.removeDirectory(pathname);  
        } finally{  
            ftpClientPool.returnObject(client);  
        }  
    }  
      
    /** 
     * 删除文件 单个 ,不可递归  
     * @param pathname 
     * @return 
     * @throws Exception 
     */  
    public   boolean deleteFile(String pathname) throws Exception {  
          
        FTPClient client=null;  
        try {  
            client= ftpClientPool.borrowObject();  
            return  client.deleteFile(pathname);  
        }finally{  
            ftpClientPool.returnObject(client);  
        }  
    }  
      
    /** 
     * 上传文件  
     * @param remote 
     * @param local 
     * @return 
     * @throws Exception 
     */  
    public   boolean storeFile(String remote, InputStream local) throws Exception {  
        FTPClient client=null;  
        try {  
            client= ftpClientPool.borrowObject();  
            return  client.storeFile(remote, local);  
        } finally{  
            ftpClientPool.returnObject(client);  
        }  
    }  
     
}  

ByteUtil字节工具类


package com.tingcream.ftpClientPool.util;  
  
import java.io.ByteArrayOutputStream;  
import java.io.InputStream;  
  
/** 
 * 字节工具类 
 * @author jelly 
 * 
 */  
public class ByteUtil {  
      
     public static byte[] inputStreamToByteArray(InputStream in)  {  
         try {  
             ByteArrayOutputStream out=new ByteArrayOutputStream();  
                byte[] buffer=new byte[1024*4];  
                int n=0;  
                while ( (n=in.read(buffer)) >0) {  
                    out.write(buffer,0,n);  
                }  
              return  out.toByteArray();  
                 
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }    
     }  
  
}  






关键字:  ftp  ftpClientPool
评论信息
暂无评论
发表评论

亲,您还没有登陆,暂不能评论哦! 去 登陆 | 注册

博主信息
   
数据加载中,请稍候...
文章分类
   
数据加载中,请稍候...
阅读排行
 
数据加载中,请稍候...
评论排行
 
数据加载中,请稍候...

Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1

鄂公网安备 42011102000739号