zoukankan      html  css  js  c++  java
  • SpringBoot整合自定义FTP文件连接池

    说明:通过GenericObjectPool实现的FTP连接池,记录一下以供以后使用
    环境:
    JDK版本1.8
    框架 :springboot2.1
    文件服务器: Serv-U
    1.引入依赖

    <!--ftp文件上传-->
    <dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.3</version>
    </dependency>
    <!--自定义连接池-->
    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.4.2</version>
    </dependency>

    2.创建ftp.properties

    ftp.Host=192.168.xx.xx 本机ip
    ftp.Port=21
    ftp.UserName=root
    ftp.PassWord=root
    ftp.workDir=/images
    ftp.encoding=utf-8
    ftp.root=/
    ftp.MaxTotal=100
    ftp.MinIdel=2
    ftp.MaxIdle=5
    ftp.MaxWaitMillis=3000

    3.创建配置类FtpConfig

    package com.hcq.demo.util;

    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;

    /**
    * fileName:FtpConfig
    * description:
    * author:hcq
    * createTime:2019-03-15 15:04
    */

    @Component
    @ConfigurationProperties(prefix="ftp")
    @PropertySource("classpath:ftp.properties")
    public class FtpConfig {
    private String Host;
    private int Port;
    private String UserName;
    private String PassWord;
    private String workDir;
    private String encoding;
    private String root;
    private int MaxTotal;
    private int MinIdel;
    private int MaxIdle;
    private int MaxWaitMillis;
    .......省略get set
    }

    4.创建FtpClientFactory工厂类

    package com.hcq.demo.util;

    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.pool2.PooledObject;
    import org.apache.commons.pool2.impl.DefaultPooledObject;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.apache.commons.pool2.PooledObjectFactory;

    import java.io.IOException;

    /**
    * fileName:FtpClientFactory
    * description:
    * author:hcq
    * createTime:2019-03-18 19:49
    */
    @Component
    public class FtpClientFactory implements PooledObjectFactory<FTPClient> {
    @Autowired
    FtpConfig config;
    //创建连接到池中
    @Override
    public PooledObject<FTPClient> makeObject() {
    FTPClient ftpClient = new FTPClient();//创建客户端实例
    return new DefaultPooledObject<>(ftpClient);
    }
    //销毁连接,当连接池空闲数量达到上限时,调用此方法销毁连接
    @Override
    public void destroyObject(PooledObject<FTPClient> pooledObject) {
    FTPClient ftpClient = pooledObject.getObject();
    try {
    ftpClient.logout();
    if (ftpClient.isConnected()) {
    ftpClient.disconnect();
    }
    } catch (IOException e) {
    throw new RuntimeException("Could not disconnect from server.", e);
    }
    }
    //链接状态检查
    @Override
    public boolean validateObject(PooledObject<FTPClient> pooledObject) {
    FTPClient ftpClient = pooledObject.getObject();
    try {
    return ftpClient.sendNoOp();
    } catch (IOException e) {
    return false;
    }
    }
    //初始化连接
    @Override
    public void activateObject(PooledObject<FTPClient> pooledObject) throws Exception {
    FTPClient ftpClient = pooledObject.getObject();
    ftpClient.connect(config.getHost(),config.getPort());
    ftpClient.login(config.getUserName(), config.getPassWord());
    ftpClient.setControlEncoding(config.getEncoding());
    ftpClient.changeWorkingDirectory(config.getWorkDir());
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置上传文件类型为二进制,否则将无法打开文件
    }
    //钝化连接,使链接变为可用状态
    @Override
    public void passivateObject(PooledObject<FTPClient> pooledObject) throws Exception {
    FTPClient ftpClient = pooledObject.getObject();
    try {
    ftpClient.changeWorkingDirectory(config.getRoot());
    ftpClient.logout();
    if (ftpClient.isConnected()) {
    ftpClient.disconnect();
    }
    } catch (IOException e) {
    throw new RuntimeException("Could not disconnect from server.", e);
    }
    }
    //用于连接池中获取pool属性
    public FtpConfig getConfig() {
    return config;
    }
    }

    5.创建FtpPool连接池

    package com.hcq.demo.util;

    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.pool2.impl.GenericObjectPool;
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;


    /**
    * fileName:ftpPool
    * description:FTP连接池
    * 1.可以获取池中空闲链接
    * 2.可以将链接归还到池中
    * 3.当池中空闲链接不足时,可以创建链接
    * author:hcq
    * createTime:2019-03-16 9:59
    */
    @Component
    public class FtpPool {
    FtpClientFactory factory;
    private final GenericObjectPool<FTPClient> internalPool;
    //初始化连接池
    public FtpPool(@Autowired FtpClientFactory factory){
    this.factory=factory;
    FtpConfig config = factory.getConfig();
    GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
    poolConfig.setMaxTotal(config.getMaxTotal());
    poolConfig.setMinIdle(config.getMinIdel());
    poolConfig.setMaxIdle(config.getMaxIdle());
    poolConfig.setMaxWaitMillis(config.getMaxWaitMillis());
    this.internalPool = new GenericObjectPool<FTPClient>(factory,poolConfig);
    }
    //从连接池中取连接
    public FTPClient getFTPClient() {
    try {
    return internalPool.borrowObject();
    } catch (Exception e) {
    e.printStackTrace();
    return null;
    }
    }
    //将链接归还到连接池
    public void returnFTPClient(FTPClient ftpClient) {
    try {
    internalPool.returnObject(ftpClient);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    /**
    * 销毁池子
    */
    public void destroy() {
    try {
    internalPool.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }


    6.创建FtpUtil类

    package com.hcq.demo.util;

    import org.apache.commons.net.ftp.FTPClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.io.ResourceLoader;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.MultipartFile;

    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.UUID;

    /**
    * fileName:FTP工具类
    * description:提供文件上传和下载
    * author:hcq
    * createTime:2019-03-16 8:55
    */
    @Component
    public class FtpUtil {
    @Autowired
    FtpConfig config;
    @Autowired
    private ResourceLoader resourceLoader;
    @Autowired
    FtpPool pool;
    /**
    * Description: 向FTP服务器上传文件
    *
    * @Version2.0
    * @param file
    * 上传到FTP服务器上的文件
    * @return
    * 成功返回文件名,否则返回null
    */
    public String upload(MultipartFile file) throws Exception {
    FTPClient ftpClient = pool.getFTPClient();
    //开始进行文件上传
    String fileName=UUID.randomUUID()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
    InputStream input=file.getInputStream();
    try {
    boolean result=ftpClient.storeFile(fileName,input);//执行文件传输
    if(!result){//上传失败
    throw new RuntimeException("上传失败");
    }
    }catch(Exception e){
    e.printStackTrace();
    return null;
    }finally {//关闭资源
    input.close();
    System.out.println("开始归还连接");
    pool.returnFTPClient(ftpClient);//归还资源
    }
    return fileName;
    }
    /**
    * Description: 从FTP服务器下载文件
    *
    * @Version1.0
    * @param fileName
    * FTP服务器中的文件名
    * @param resp
    * 响应客户的响应体
    */
    public void downLoad(String fileName,HttpServletResponse resp) throws IOException {
    FTPClient ftpClient = pool.getFTPClient();
    resp.setContentType("application/force-download");// 设置强制下载不打开 MIME
    resp.addHeader("Content-Disposition", "attachment;fileName="+fileName);// 设置文件名
    //将文件直接读取到响应体中
    OutputStream out = resp.getOutputStream();
    ftpClient.retrieveFile(config.getWorkDir()+"/"+fileName, out);
    out.flush();
    out.close();
    pool.returnFTPClient(ftpClient);
    }
    /**
    * Description: 从FTP服务器读取图片
    *
    * @Version1.0
    * @param fileName
    * 需要读取的文件名
    * @return
    * 返回文件对应的Entity
    */
    public ResponseEntity show(String fileName){
    String username=config.getUserName();
    String password=config.getPassWord();
    String host=config.getHost();
    String work=config.getWorkDir();
    //ftp://root:root@192.168.xx.xx/+fileName
    return ResponseEntity.ok(resourceLoader.getResource("ftp://"+username+":"+password+"@"+host+work+"/"+fileName));
    }


    }
    ---------------------
    作者:Keepalived。
    来源:CSDN
    原文:https://blog.csdn.net/qq_39914581/article/details/88660133
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    e621. Activating a Keystroke When Any Child Component Has Focus
    e587. Filling Basic Shapes
    e591. Drawing Simple Text
    e595. Drawing an Image
    e586. Drawing Simple Shapes
    e636. Listening to All Key Events Before Delivery to Focused Component
    在 PL/SQL 块的哪部分可以对初始变量赋予新值? (选择1项)
    Oracle数据库中,在SQL语句中连接字符串的方法是哪个?(选择1项)
    你判断下面语句,有什么作用?(单选)
    Oracle数据库表空间与数据文件的关系描述正确的是( )
  • 原文地址:https://www.cnblogs.com/pangguoming/p/10910655.html
Copyright © 2011-2022 走看看