`
bai2mumu
  • 浏览: 5947 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java ftpClient 连接池设计

阅读更多

1、FtpManager 类中,需要创建连接池管理的Map

private static ConcurrentHashMap<String, FtpClientPool> pools = new ConcurrentHashMap<String, FtpClientPool>();

 

2、定义具体的操作方法,如删除

public static void deleteFiles(List<FtpEntity> ftpEntitys, String filePath, Set<String> fileNames) throws Exception {

        if (null == fileNames || fileNames.size() <= 0) {

            return;

        }

        Exception e = null;

        for (FtpEntity ftpEntity : ftpEntitys) {

            FTPClient ftpClient = null;

            try {

                ftpClient = borrowClient(ftpEntity);

                makeDirectory(ftpClient, ftpEntity.getTemp(), filePath);

                for (String fileName : fileNames) {

                    try {

                        ftpClient.deleteFile(fileName);

                    } catch (Exception e1) {

                        LOGGER.log(Level.SEVERE, "delete " + fileName + " error", e1);

                    }

                }

            } catch (Exception ex) {

                LOGGER.log(Level.SEVERE, "uploadFile error", ex);

                returnBrokenClient(ftpClient);

                ftpClient = null;

                e = ex;

            } finally {

                if (ftpClient != null) {

                    returnClient(ftpClient);

                }

            }

        }

        if (null != e) {

            throw e;

        }

 

    }

 

3、borrowClient 是哪里来的呢??

    public static FTPClient borrowClient(FtpEntity ftpEntity) {

        String url = ftpEntity.getUrl();

        if (!url.endsWith(SPLITTER)) {

            url = url + SPLITTER;

        }

        String hostName = url.substring(FTP_FIX, url.indexOf(SPLITTER, FTP_FIX));

        String username = ftpEntity.getUsername();

        String password = ftpEntity.getPassword();

        String poolId = constructPoolId(hostName, username, password);

        FtpClientPool pool = pools.get(poolId);

        if (pool == null) {

            final FtpClientPool value = new FtpClientPool(hostName, username, password);

            pool = pools.putIfAbsent(poolId, value);

            if (pool == null) {

                pool = value;

            }

        }

        return pool.borrowClient();

    }

4、FtpClientPool 哪里来的呢? 它是ftpManager 的一个内部类

private static class FtpClientPool {

 

        private final GenericObjectPool<FTPClient> internalPool;

 

        private FtpClientPool(String hostname, String username, String password) {

            this.internalPool = new GenericObjectPool<FTPClient>(new FtpClientFactory(hostname, username, password));

            // this is important,change to root dir when borrow from pool,ref validateObject method.

            this.internalPool.setTestOnBorrow(true);

            this.internalPool.setMaxTotal(50);

            this.internalPool.setMaxIdle(16);

            // this.internalPool.setMinEvictableIdleTimeMillis(60000);

            // this.internalPool.setTimeBetweenEvictionRunsMillis(60000);

            // this.internalPool.setTestWhileIdle(true);

            this.internalPool.setBlockWhenExhausted(true);

            // this.internalPool.setNumTestsPerEvictionRun(10);

            // this.internalPool.setMaxTotal(Integer.MAX_VALUE);

            this.internalPool.setMaxWaitMillis(MaxWaitMillis);

            // this.internalPool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);

        }

 

        /**

         * 功能描述: <br>

         * 获取链接 〈功能详细描述〉

         * 

         * @return

         * @see [相关类/方法](可选)

         * @since [产品/模块版本](可选)

         */

        public FTPClient borrowClient() {

            try {

                return this.internalPool.borrowObject();

            } catch (Exception e) {

                throw new RuntimeException("Could not borrowClient from pool", e);

            }

        }

 

        /**

         * 功能描述: <br>

         * 初始化连接 〈功能详细描述〉

         * 

         * @param client

         * @see [相关类/方法](可选)

         * @since [产品/模块版本](可选)

         */

        public void returnClient(FTPClient client) {

            try {

                this.internalPool.returnObject(client);

            } catch (Exception e) {

//                LOGGER.log(Level.WARNING, "Could not returnClient from pool", e);

            }

        }

 

        public void returnBrokenClient(FTPClient client) {

            try {

                this.internalPool.invalidateObject(client);

            } catch (Exception e) {

//                LOGGER.log(Level.WARNING, "Could not returnBrokenClient from pool", e);

            }

        }

 

        /**

         * 功能描述: <br>

         * 销毁链接 〈功能详细描述〉

         * 

         * @see [相关类/方法](可选)

         * @since [产品/模块版本](可选)

         */

        public void destroy() {

            try {

                this.internalPool.close();

            } catch (Exception e) {

//                LOGGER.log(Level.WARNING, "Could not destroy pool", e);

            }

        }

    }

 

5、FtpClientFactory 哪里来的呢?它也是一个内部类

private static class FtpClientFactory implements PooledObjectFactory<FTPClient> {

 

        private String hostname;

 

        private String username;

 

        private String password;

 

        private FtpClientFactory(String hostname, String username, String password) {

            this.hostname = hostname;

            this.username = username;

            this.password = password;

        }

 

        /*

         * (non-Javadoc)

         * @see org.apache.commons.pool.BasePoolableObjectFactory#makeObject()

         */

        public FtpClientWrapper create() throws Exception {

            FtpClientWrapper ftpClient = null;

            Boolean flag = false;

            Exception e = null;

            for (int i = 0; i < RECONNECT_TIMES; i++) {

                try {

                    ftpClient = new FtpClientWrapper(this.hostname, this.username, this.password);

                    ftpClient.setConnectTimeout(CONNECT_TIMEOUT);

                    // ftpClient.setDefaultTimeout(CONNECT_TIMEOUT);

                    ftpClient.setControlEncoding("utf-8");

                    ftpClient.connect(hostname);

                    ftpClient.setDataTimeout(DATA_TIMEOUT);

                    int reply = ftpClient.getReplyCode();

                    if (!FTPReply.isPositiveCompletion(reply)) {

                        ftpClient.disconnect();

                        throw new Exception("FTP Connect fail");

                    }

                    if (!ftpClient.login(username, password)) {

                        ftpClient.disconnect();

                        throw new Exception("Invalid username and password");

                    }

                    ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

                    ftpClient.setBufferSize(BUFFER_SIZE);

                    ftpClient.enterLocalPassiveMode();

                    ftpClient.setRootDir(ftpClient.printWorkingDirectory());

                    flag = true;

                    break;

                } catch (Exception ex) {

//                    LOGGER.log(Level.WARNING, "test....Can not create ftpClient," + this.hostname, ex);

                    try {

                        destroyObject(ftpClient);

                    } catch (Exception e1) {

//                        LOGGER.log(Level.WARNING, "test...Can not close ftpClient," + this.hostname, e1);

                    }

                    e = ex;

                    Thread.sleep(RECONNECT_SLEEP_TIME);

                }

            }

            if (!flag) {

//                LOGGER.log(Level.WARNING, "test....Can not create ftpClient in three times," + this.hostname);

                try {

                    destroyObject(ftpClient);

                } catch (Exception e1) {

//                    LOGGER.log(Level.WARNING, "Can not close ftpClient", e1);

                }

                throw new Exception(hostname + " cat not connect.", e);

            }

            return ftpClient;

        }

 

        public void destroyObject(FTPClient ftpClient) throws Exception {

            closeFtpClient(ftpClient);

        }

 

        @Override

        public PooledObject<FTPClient> makeObject() throws Exception {

            // TODO Auto-generated method stub

            return new DefaultPooledObject<FTPClient>(create());

        }

 

        @Override

        public void destroyObject(PooledObject<FTPClient> p) throws Exception {

            closeFtpClient(p.getObject());

        }

 

        @Override

        public boolean validateObject(PooledObject<FTPClient> p) {

            try {

                ((FtpClientWrapper) p.getObject()).changeToRootDir();

                return true;

            } catch (Exception e) {

//                LOGGER.log(Level.WARNING, "failed to changeToRootDir,validate failed.");

                throw new RuntimeException("Failed to validate client: " + e, e);

            }

        }

 

        @Override

        public void activateObject(PooledObject<FTPClient> p) throws Exception {

            // TODO Auto-generated method stub

 

        }

 

        @Override

        public void passivateObject(PooledObject<FTPClient> p) throws Exception {

            // TODO Auto-generated method stub

 

        }

 

    }

 

6、FtpClientWrapper 哪里来的呢,没错,还是内部类

public static class FtpClientWrapper extends FTPClient {

 

        private String poolId;

 

        private String rootDir;

 

        public FtpClientWrapper(String ip, String username, String password) {

            super();

            this.poolId = constructPoolId(ip, username, password);

        }

 

        /**

         * 功能描述: <br>

         * get set方法 〈功能详细描述〉

         * 

         * @return : id

         * @see [相关类/方法](可选)

         * @since [产品/模块版本](可选)

         */

        public String getPoolId() {

            return poolId;

        }

 

        /**

         * 功能描述: <br>

         * get set方法 〈功能详细描述〉

         * 

         * @see [相关类/方法](可选)

         * @since [产品/模块版本](可选)

         */

        public void setRootDir(String rootDir) {

            this.rootDir = rootDir;

        }

 

        /**

         * 功能描述: <br>

         * 返回根目录 〈功能详细描述〉

         * 

         * @throws Exception

         * @see [相关类/方法](可选)

         * @since [产品/模块版本](可选)

         */

        public void changeToRootDir() throws Exception {

            changeWorkingDirectory(rootDir);

        }

    }

 

分享到:
评论
1 楼 OneZhous 2017-11-26  
FtpEntity 这个类是你自己封装的吧,能共享么

相关推荐

    FTPClient连接池

    使用apache的commons-pool2 构建 FTPClient连接池 有FtpClientFactory、FtpClientPool、FtpConfig、FtpOperate 四个类组成 还有ftp连接池的一些配置参数信息在ftp.properties文件中 注释完整欢迎大家下载使用

    Java FTPClient连接池的实现

    Java FTPClient连接池的实现 在这篇文章中,我们主要介绍了Java FTPClient连接池的实现。首先,我们需要了解为什么需要使用连接池。创建和销毁FTPClient对象是非常耗费资源的操作,因此,我们可以使用连接池来复用...

    springboot集成ftp连接池工具

    本文将深入探讨如何在Spring Boot项目中集成FTP连接池,以解决并发用户上传附件时的性能问题。 首先,我们需要引入相关的依赖。在Spring Boot项目中,可以使用Apache Commons Net库来实现FTP功能,并使用Apache ...

    Spring Boot整合FTPClient线程池的实现示例

    在 Spring Boot 项目中,我们可以使用 Apache 的 common-pool 包来协助我们开发连接池。具体来说,我们需要实现 common-pool 包中的 ObjectPool 和 PoolableObjectFactory 两个接口。 首先,我们需要在 pom 文件中...

    FtpClient写的java FTP工具

    在这个工具中,可能会封装上述的基本FTP操作,并可能提供更友好的API,如异步处理、错误处理、连接池管理等功能,以简化开发者的使用。 总结一下,`FtpClient`是Java中实现FTP功能的重要工具,它提供了丰富的接口来...

    FTPCLIENT_commons-net-1.4.1_jakarta-oro-2.0.8

    同时,为了处理异常和优化性能,还会考虑使用连接池、重试机制、断点续传等功能。 总的来说,通过结合`commons-net-1.4.1.jar`和`jakarta-oro-2.0.8.jar`这两个库,Java开发者可以构建出强大且灵活的FTP客户端应用...

    java ftp 上传 IIS 展示,代码+文档

    另一个可能进行了二次封装,意味着它在基础功能之上添加了更高级的功能,比如错误处理、连接池管理或者更友好的API,以提高代码的可读性和复用性。 在JDK 1.7版本中,Java已经内置了`java.net.FTPSClient`和`java...

    java FTP上传文件,下载文件

    `FTPNet.java`可能包含了`FTPClient`的使用逻辑,而`FtpConManager.java`可能是一个管理FTP连接的类,用于控制连接池,确保资源的有效管理和复用。 `FTPNet.java`可能包含以下关键方法: - `connectToFtpServer...

    JAVA上百实例源码以及开源项目源代码

    [ConfigLine.java] 控制条类 [RoundBox.java] 限定选择控件 [MonthMaker.java] 月份表算法类 [Pallet.java] 调色板,统一配色类 Java扫雷源码 Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接与浏览,...

    JAVA上百实例源码以及开源项目

    百度云盘分享 ... Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText();...

    Java实现的FTP连接与数据浏览程序

    此外,考虑到FTP服务器可能有并发限制,我们需要管理好连接池,避免过多的并发连接导致服务器拒绝服务。 总的来说,Java实现的FTP连接与数据浏览程序涉及网络编程、文件操作、流处理、错误处理等多个方面的知识。...

    基于JAVA的网络通讯系统设计与实现(论文+系统

    9. **性能优化**:通过缓存策略、负载均衡、连接池等技术,可以优化Java网络通讯系统的性能,提高响应速度和并发处理能力。 10. **测试与调试**:单元测试、集成测试和压力测试是保证网络通讯系统质量的关键步骤。...

    JavaFtp实例,实现文件下载和读取

    此外,如果需要处理大量文件或频繁的FTP操作,考虑使用多线程和连接池以提高性能。 总之,Java FTP功能为我们提供了一种可靠的方式来与FTP服务器交互,无论是下载文件还是读取内容,都是业务系统中常见且实用的功能...

    ftp.rar_ftp_ftp java_java ftp 下载

    在IT行业中,FTP(File Transfer Protocol)是一种广泛用于在互联网上进行文件传输的标准协议。Java作为一种多用途且跨...在实际开发中,根据项目需求,可能还需要考虑更多细节,如连接池管理、线程安全、重试策略等。

    java网络编程下载器源代码

    高级的下载器可能还会涉及连接池的使用,以减少建立和关闭Socket的开销;或者使用NIO(非阻塞I/O)来提高性能。Java的`java.nio`包提供了这些功能的支持。 通过研究和实践这个Java网络编程下载器源代码,学习者可以...

    JAVA2网络协议内幕-2

    此外,Apache HttpClient库提供更高级的功能,如多线程、连接池和自定义请求头。 4. **FTP协议**:文件传输协议(FTP)用于在网络上进行文件传输。Java通过java.net.FTPSClient和java.net.FTPClient类提供了FTP和...

    Http下载器 FTP下载器(java)

    10. **性能优化**:可以通过缓存优化、连接池管理等方式提升下载性能。例如,使用HTTP/1.1的Keep-Alive特性保持连接,减少握手开销;或者使用线程池避免频繁创建销毁线程。 综上所述,"Http下载器 FTP下载器(java...

    java上传和下载所需要的jar包

    它支持文件上传和下载,提供了异步和同步的API,以及连接池和重试策略。 6. **FTP/FTPS**:如果需要与FTP或安全的FTPS服务器交互,可以使用`java.net`包中的`FTPClient`类,或者使用第三方库如Apache Commons Net。...

Global site tag (gtag.js) - Google Analytics