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
版权声明:本文为博主原创文章,转载请附上博文链接!
SpringBoot整合自定义FTP文件连接池的更多相关文章
- (二)SpringBoot整合常用框架Druid连接池
一,在Pom.xml文件加入依赖 找到<dependencies></dependencies>标签,在标签中添加Druid依赖 <dependency> < ...
- 【转】SSH中 整合spring和proxool 连接池
[摘要:比来做的一个项目中应用到了毗邻池技巧,大概我们人人比拟认识的开源毗邻池有dbcp,c3p0,proxool.对那三种毗邻池来讲,从机能战失足率来讲,proxool轻微比前两种好些.本日我首要简 ...
- SpringMVC+Spring+Mybatis整合,使用druid连接池,声明式事务,maven配置
一直对springmvc和mybatis挺怀念的,最近想自己再搭建下框架,然后写点什么. 暂时没有整合缓存,druid也没有做ip地址的过滤.Spring的AOP简单配置了下,也还没具体弄,不知道能不 ...
- Spring整合JDBC和Druid连接池
我的博客名为黑客之谜,喜欢我的,或者喜欢未来的大神,点一波关注吧!顺便说一下,双十二快到了,祝大家双十二快乐,尽情的买买买~ 如果转载我的文章请标明出处和著名,谢谢配合. 我的博客地址为: https ...
- Spring整合Hibernate_数据源Datasource_dbcp连接池
1, Spring指定 datasource DataSource接口,在javax.sql包,里边有一个getConnection()方法.提供了标准化的取得连接的方式.只要实现了这个接口.Sun ...
- springboot整合OSS实现文件上传
OSS 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量.安全.低成本.高可靠的云存储服务.OSS可用于图片.音视频.日志等海量文件的存储.各种终端 ...
- SpringBoot性能优化之HikariCP连接池
以前一直使用阿里Druid数据库连接池,这段时间听说有个号称速度最快.代码最简的后起之秀——HikariCP,于是动手实践一下 1.依赖如下: <?xml version="1.0&q ...
- SpringBoot整合SpringMVC完成文件上传
1.编写Controller /** * SPringBoot文件上传 */ //@Controller @RestController //表示该类下的方法的返回值会自动做json格式的转换 pub ...
- Springboot整合SpringSecurity--对静态文件进行权限管理
文章目录 一.要求 二.依赖管理 三.配置config文件 四.扩展 一.要求 index.html 可以被所有用户访问 1.html只能被VIP1访问 2.html只能被VIP2访问 3.html只 ...
随机推荐
- 数据结构or算法
其实长久以来 mrxfyxj一直纠结着数据结构和算法到底有什么区别 只要学了一个算法就在惋惜她为什么不能是数据结构 产生这种想法的原因是mrxf觉得他blog里数据结构的东西很少 而mrxf自身又有一 ...
- 怎样删掉vc++ 对话框中的蓝色虚线框
选择"格式"--"切换辅助线"或者是快捷键alt+o , g
- Web协议详解与抓包实战:HTTP1协议-如何管理跨代理服务器的长短连接?(4)
一.HTTP 连接的常见流程 二.从 TCP 编程上看 HTTP 请求处理 三.短连接与长连接 四.Connection 仅针对当前连接有效 五.代理服务器对长连接的支持 未设置代理服务器 设置代理 ...
- 使用Intellij idea新建Java Web项目(servlet) 原理及初步使用
准备 JDK (配置JDK_HOME\bin 和 CLASSPATH) 注:JDK8下载已经需要注册了,请使用JDK11(现在是官方长期支持的版本) 对于我们新手来说,JD ...
- tecplot无法处理高版本fluent导出的Ensight格式
高版本的Fluent完成计算,将计算结果导出为Ensight格式,然后再导入tecplot当中进行后处理的时候会遇见如下的错误: 但是将低版本的Fluent计算结果导出为Ensight格式,却可以顺利 ...
- Leetcode 344:Reverse String 反转字符串(python、java)
Leetcode 344:Reverse String 反转字符串 公众号:爱写bug Write a function that reverses a string. The input strin ...
- thinkphp中怎么使用phpmailer发送邮件
phpmailer发送邮件是php开发者首选的一个邮件发送插件了,下面我来介绍怎么集成phpmailer到thinkphp框架了,有需要了解的朋友可参考. phpmailer发送邮件功能很强大,今天真 ...
- AtomicReference示例
对引用类型的原子性操作 /** * *对引用变量的原子操作 note: *在java中对引用类型的变量,赋值是原子性的,为什么还要有atomicReference,假如要对一个引用类型进行比较,设置等 ...
- 两数相加II--链表
题目 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 进阶: ...
- AspNet Core使用Mysql一些问题及解决方案
本文假设的你的AspNet Core 2.2的Web程序通过EntityFrameworkCore连接使用MSSQL数据库,能正常使用. 如何想转为使用Mysql,其实不难. 1.安装Mysql这个简 ...