前言

基于springboot,使用ftpserver快速搭建一个FTP服务端。

搭建过程很简单,我们把过程分成4个步骤,一分钟内快速完成构建。

实现功能

  1. 使用ftpserver快速搭建一个FTP服务端
  2. 支持多个用户多个目录上传目录
  3. 支持FTP主动模式(单个端口)和被动模式(范围随机端口)
  4. 监听ftpserver状态,方便进行更细粒度权限控制等定制功能

依赖项

gradle方式:

 implementation 'org.apache.ftpserver:ftpserver-core:1.2.0'

maven方式

<dependency><groupId>org.apache.ftpserver</groupId><artifactId>ftpserver-core</artifactId><version>1.2.0</version>
</dependency>

配置文件

首先,在springboot项目中增加两个配置,创建ftpserver.properties配置和在application.properties基础上增加ftp配置。配置如下:

1、ftpserver.properties配置

#表示admin的密码是12345,以下都是admin的参数设置,可以设置多个用户
ftpserver.user.admin.userpassword=eguid
ftpserver.user.admin.homedirectory=C://ftp
ftpserver.user.admin.enableflag=true
ftpserver.user.admin.writepermission=true
ftpserver.user.admin.maxloginnumber=0
ftpserver.user.admin.maxloginperip=0
ftpserver.user.admin.idletime=0
ftpserver.user.admin.uploadrate=0
ftpserver.user.admin.downloadrate=0
#用户名是eguid的用户配置
ftpserver.user.eguid.userpassword=eguid
ftpserver.user.eguid.homedirectory=C://ftp/eguid
ftpserver.user.eguid.enableflag=true
ftpserver.user.eguid.writepermission=true
ftpserver.user.eguid.maxloginnumber=0
ftpserver.user.eguid.maxloginperip=0
ftpserver.user.eguid.idletime=0
ftpserver.user.eguid.uploadrate=0
ftpserver.user.eguid.downloadrate=0

2、application.properties配置

在原有application.properties基础上增加以下配置

##FTP内嵌服务器
#ftp连接端口
ftp.port=8021
# ftp主动模式端口
ftp.activePort=8022
#ftp被动模式数据传输端口
ftp.passivePorts=50021-60021

初始化FTP服务

该类继承自ApplicationRunner类,会在springboot服务启动后自动启动。
由于没有考虑到springboot重启的情况,所以ftp服务会出现无法释放端口的问题,解决该问题请参考博主另一篇文章《springboot内嵌ftpserver服务端在服务重启后报错端口被占用解决办法》,就可以解决跟随springboot重启ftp服务的问题。

import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.ftplet.FtpException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;/*** 初始化ftp服务器* @author 汤姆猫不是猫*/
@Component
public class InitFtpServer implements ApplicationRunner {public static final Logger log = LoggerFactory.getLogger(InitFtpServer.class);@Autowiredprivate FtpServer server;@Overridepublic void run(ApplicationArguments args) throws Exception {try {server.start();log.info("汤姆猫不是猫: ftp server start success ");} catch (FtpException e) {e.printStackTrace();log.error("汤姆猫不是猫: ftp server start error {}", e);}}
}

ftpserver服务主动模式和被动模式参数配置


import org.apache.ftpserver.DataConnectionConfigurationFactory;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;import java.util.HashMap;
import java.util.Map;/*** ftpserver配置,含主动模式和被动模式* @author 汤姆猫不是猫*/
@Configuration
public class FtpServerConfig extends CachingConfigurerSupport {@Value("${ftp.port}")private Integer ftpPort;@Value("${ftp.activePort}")private Integer ftpActivePort;@Value("${ftp.passivePorts}")private String ftpPassivePorts;@Beanpublic FtpServer createFtpServer() {FtpServerFactory serverFactory = new FtpServerFactory();ListenerFactory factory = new ListenerFactory();//这个只是控制端口,还有主动模式端口和被动模式下的某个范围端口factory.setPort(ftpPort);factory.setIdleTimeout(10);//被动模式DataConnectionConfigurationFactory dataConnectionConfigurationFactory = new DataConnectionConfigurationFactory();dataConnectionConfigurationFactory.setIdleTime(30);dataConnectionConfigurationFactory.setActiveLocalPort(ftpActivePort);//主动模式端口dataConnectionConfigurationFactory.setPassiveIpCheck(true);dataConnectionConfigurationFactory.setPassivePorts(ftpPassivePorts);被动模式使用的端口范围factory.setDataConnectionConfiguration(dataConnectionConfigurationFactory.createDataConnectionConfiguration());// 替换默认的监听器serverFactory.addListener("default", factory.createListener());PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();try {ClassPathResource classPathResource = new ClassPathResource("ftpserver.properties");userManagerFactory.setUrl(classPathResource.getURL());} catch (Exception e) {throw new RuntimeException("汤姆猫不是猫:配置文件ftpserver.properties不存在");}userManagerFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor());serverFactory.setUserManager(userManagerFactory.createUserManager());Map<String, Ftplet> m = new HashMap<String, Ftplet>();m.put("miaFtplet", new FtpServerListener());serverFactory.setFtplets(m);// 创建ftpserverFtpServer server = serverFactory.createServer();return server;}
}

监听ftp服务运行状态

import org.apache.ftpserver.ftplet.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.File;
import java.io.IOException;
import java.util.UUID;/*** 监听ftpserver服务上传和下载情况* @author 汤姆猫不是猫*/
public class FtpServerListener extends DefaultFtplet {public static final Logger log = LoggerFactory.getLogger(FtpServerListener.class);/*** 开始连接*/@Overridepublic FtpletResult onConnect(FtpSession session) throws FtpException,IOException {UUID sessionId = session.getSessionId();if(sessionId!=null) {log.info("{}尝试登录ftpserver", sessionId.toString());}User user = session.getUser();if(user!=null&&user.getName()!=null){log.info("{}尝试使用用户名:{},密码:{}登录ftpserver.", sessionId.toString(), user.getName(), user.getPassword());}return super.onConnect(session);}/*** 关闭连接*/@Overridepublic FtpletResult onDisconnect(FtpSession session) throws FtpException,IOException {UUID sessionId = session.getSessionId();if(sessionId!=null) {log.info("{}关闭ftpserver连接", sessionId.toString());}User user = session.getUser();if(user!=null&&user.getName()!=null){log.info("{}用户名:{}关闭ftpserver连接.",  sessionId.toString(), user.getName());}return super.onDisconnect(session);}/*** 开始上传*/@Overridepublic FtpletResult onUploadStart(FtpSession session, FtpRequest request)throws FtpException, IOException {//获取上传文件的上传路径String path = session.getUser().getHomeDirectory();//自动创建上传路径File file = new File(path);if (!file.exists()) {file.mkdirs();}//获取上传用户String name = session.getUser().getName();//获取上传文件名String filename = request.getArgument();log.info("用户:'{}',上传文件到目录:'{}',文件名称为:'{}',状态:开始上传~", name, path, filename);return super.onUploadEnd(session, request);}/*** 上传完成*/@Overridepublic FtpletResult onUploadEnd(FtpSession session, FtpRequest request)throws FtpException, IOException {//获取上传文件的上传路径String path = session.getUser().getHomeDirectory();//获取上传用户String name = session.getUser().getName();//获取上传文件名String filename = request.getArgument();File file = new File(path + "/" + filename);if (file.exists()) {System.out.println(file);}log.info("用户:'{}',上传文件到目录:'{}',文件名称为:'{},状态:成功!'", name, path, filename);return super.onUploadStart(session, request);}@Overridepublic FtpletResult onDownloadStart(FtpSession session, FtpRequest request) throws FtpException, IOException {return super.onDownloadStart(session, request);}@Overridepublic FtpletResult onDownloadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException {return super.onDownloadEnd(session, request);}}

以上步骤完成后,启动springboot。使用ftpclient工具尝试连接配置文件里的8021控制端口,如以下图所示,可以看到已经连接成功。

end


以上就是全部搭建过程,是不是很简单。如果觉得博主写得还不错,欢迎“关注、点赞、收藏”一键三连!


springboot快速搭建ftpserver服务端相关推荐

  1. 快速搭建Kerberos服务端及入门使用

    快速搭建Kerberos服务端及入门使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Kerberos是一种网络身份验证协议.它旨在通过使用秘密密钥加密为客户端/服务器应用程序提 ...

  2. SpringBoot+Axis2搭建WebService服务端

    SpringBoot+Axis2搭建WebService服务端 之前用过Spring + Axis2搭建过WebService项目,网上也有很多资料教程,最近需要在一个SpringBoot项目中添加A ...

  3. 一文学会快速搭建Janus服务端

    1.概述 想要了解Janus,首先需要知道WebRTC以及Janus和WebRTC之间的关系,本文将会对这些内容做简单的介绍,同时也会介绍一下Janus的架构,Janus可以实现的功能,并展示如何快速 ...

  4. Spring Boot如何在最短时间里快速搭建微服务框架,详细教程贡上

    前言: Spring Boot是为了简化Spring应用的创建.运行.调试.部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置. 简单来说,它提供了一堆依赖打包,并 ...

  5. 大疆无人机基于自搭建RTMP服务端推流直播

    思路 大疆在手机端提供了软件DJI GO 4控制飞行参数等,其中包含自定义RTMP接口来向第三方推流进行直播业务,而我们可以利用这种直播的思路来完成画面传输. 环境 精灵Phantom 4 Pro V ...

  6. Azure 中快速搭建 FTPS 服务

    FTP,FTPS 与 SFTP 的区别 FTP (File Transfer Protocol)是一种常用的文件传输协议,在日常工作中被广泛应用.不过,FTP 协议使用明文传输.如果文件传输发生在公网 ...

  7. 阿里云ESC搭建SVN服务端

    CentOS7)下yum命令快速安装svn服务端,学习在思考中独孤中度过,在孤独中进取! 01.SVN服务的安装(subversion) 02.ESC安全组策略 1.在线安装svn服务 $ sudo ...

  8. 如何在 MacOS 环境下搭建 SVN 服务端环境

    文章目录 在服务端创建资源仓库 资源仓库访问权限配置 给资源仓库添加用户 配置用户组及用户的权限 启动 SVN 服务器 停止 SVN 服务器 SVN 是一个使用十分广泛的开放源代码的版本控制系统.在 ...

  9. vue.js+koa2项目实战(四)搭建koa2服务端

    搭建koa2服务端 安装两个版本的koa 一.版本安装 1.安装 koa1 npm install koa -g 注:必须安装到全局 2.安装 koa2 npm install koa@2 -g 二. ...

  10. HTML+JS+websocket 实现联机“游戏王”对战(十)- 搭建游戏服务端

    目录: 游戏王联机卡牌对战 1 - 前言 游戏王联机卡牌对战 2 - 联机模式 游戏王联机卡牌对战 3 - 界面布局 游戏王联机卡牌对战 4 - 卡组系统 游戏王联机卡牌对战 5 - 卡片选中系统 游 ...

最新文章

  1. iOS 8以上的设置的跳转
  2. 《极乐迪斯科》:一趟充满新奇的旅程 ,一款里程碑式的 CRPG
  3. 网页信息抓取进阶 支持Js生成数据 Jsoup的不足之处
  4. 开放式式商业模式_什么是开放式领导?
  5. 2015.12.24 OC中的装箱
  6. 操作系统—内存的连续分配管理方式
  7. 华为HG255D超级管理员密码
  8. 初二生态系统思维导图_初中生物生态系统知识点思维导图
  9. PHP留言板系统设计图,简单实现PHP留言板功能
  10. Win10华硕atk驱动怎么安装_win10台式机网卡驱动如何安装
  11. 初识内存控制器和SDRAM【一文了解】
  12. CQ40 519TX不刷BIOS完美解决声卡问题方法
  13. go :Multiple-value strconv.Atoi() (int, error) in single-value context
  14. TypeError: can‘t convert cuda:0 device type tensor to numpy. Use Tensor.cpu()
  15. html5首字母大小写,css中如何设置英文首字母大写
  16. Python-懒人必备-语音小助手
  17. 中国移动、天猫都在用的区块链抽奖,了解一下?
  18. IDL读取ASCII文件
  19. 数据挖掘之房价预测任务
  20. 51单片机电机测速程序c语言,单片机电机测速程序

热门文章

  1. 初中计算机面试题目,2019年上半年教师资格证面试《初中信息技术》真题及答案...
  2. html图片绝对地址相对地址,HTML中background的图片地址是相对地址吗?
  3. 【Python实战项目】做一个 刮刮乐 案例,一不小心....着实惊艳到我了。
  4. 【牛客】3002 G-eli和字符串
  5. 使用两个路由器级连实现共用一个宽带
  6. 【优先队列】Toda 2
  7. SSL原理,SSL握手过程
  8. 证明:二阶导函数大于零时为凹函数
  9. 小虾米闯江湖服务器维护中,小虾米闯江湖数据总结及中期注意事项一览
  10. Vue Websocket 监听 websocket.readyState