springboot快速搭建ftpserver服務(wù)端的詳細(xì)步驟
前言
基于springboot,使用ftpserver快速搭建一個(gè)FTP服務(wù)端。
搭建過(guò)程很簡(jiǎn)單,我們把過(guò)程分成4個(gè)步驟,一分鐘內(nèi)快速完成構(gòu)建。
實(shí)現(xiàn)功能
- 使用ftpserver快速搭建一個(gè)FTP服務(wù)端
- 支持多個(gè)用戶多個(gè)目錄上傳目錄
- 支持FTP主動(dòng)模式(單個(gè)端口)和被動(dòng)模式(范圍隨機(jī)端口)
- 監(jiān)聽(tīng)ftpserver狀態(tài),方便進(jìn)行更細(xì)粒度權(quán)限控制等定制功能
依賴項(xiàng)
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>
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.2.0</version>
</dependency>配置文件
首先,在springboot項(xiàng)目中增加兩個(gè)配置,創(chuàng)建ftpserver.properties配置和在application.properties基礎(chǔ)上增加ftp配置。配置如下:
1、ftpserver.properties配置
#表示admin的密碼是12345,以下都是admin的參數(shù)設(shè)置,可以設(shè)置多個(gè)用戶 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基礎(chǔ)上增加以下配置
##FTP內(nèi)嵌服務(wù)器 #ftp連接端口 ftp.port=8021 # ftp主動(dòng)模式端口 ftp.activePort=8022 #ftp被動(dòng)模式數(shù)據(jù)傳輸端口 ftp.passivePorts=50021-60021
初始化FTP服務(wù)
該類繼承自ApplicationRunner類,會(huì)在springboot服務(wù)啟動(dòng)后自動(dòng)啟動(dòng)。
由于沒(méi)有考慮到springboot重啟的情況,所以ftp服務(wù)會(huì)出現(xiàn)無(wú)法釋放端口的問(wèn)題,解決該問(wèn)題請(qǐng)參考博主另一篇文章《springboot內(nèi)嵌ftpserver服務(wù)端在服務(wù)重啟后報(bào)錯(cuò)端口被占用解決辦法》,就可以解決跟隨springboot重啟ftp服務(wù)的問(wèn)題。
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服務(wù)器
* @author 湯姆貓不是貓
*/
@Component
public class InitFtpServer implements ApplicationRunner {
public static final Logger log = LoggerFactory.getLogger(InitFtpServer.class);
@Autowired
private FtpServer server;
@Override
public 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服務(wù)主動(dòng)模式和被動(dòng)模式參數(shù)配置
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配置,含主動(dòng)模式和被動(dòng)模式
* @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;
@Bean
public FtpServer createFtpServer() {
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
//這個(gè)只是控制端口,還有主動(dòng)模式端口和被動(dòng)模式下的某個(gè)范圍端口
factory.setPort(ftpPort);
factory.setIdleTimeout(10);
//被動(dòng)模式
DataConnectionConfigurationFactory dataConnectionConfigurationFactory = new DataConnectionConfigurationFactory();
dataConnectionConfigurationFactory.setIdleTime(30);
dataConnectionConfigurationFactory.setActiveLocalPort(ftpActivePort);//主動(dòng)模式端口
dataConnectionConfigurationFactory.setPassiveIpCheck(true);
dataConnectionConfigurationFactory.setPassivePorts(ftpPassivePorts);被動(dòng)模式使用的端口范圍
factory.setDataConnectionConfiguration(dataConnectionConfigurationFactory.createDataConnectionConfiguration());
// 替換默認(rèn)的監(jiān)聽(tīng)器
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);
// 創(chuàng)建ftpserver
FtpServer server = serverFactory.createServer();
return server;
}
}監(jiān)聽(tīng)ftp服務(wù)運(yùn)行狀態(tài)
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;
/**
* 監(jiān)聽(tīng)ftpserver服務(wù)上傳和下載情況
* @author 湯姆貓不是貓
*/
public class FtpServerListener extends DefaultFtplet {
public static final Logger log = LoggerFactory.getLogger(FtpServerListener.class);
/**
* 開(kāi)始連接
*/
@Override
public 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);
}
/**
* 關(guān)閉連接
*/
@Override
public FtpletResult onDisconnect(FtpSession session) throws FtpException,
IOException {
UUID sessionId = session.getSessionId();
if(sessionId!=null) {
log.info("{}關(guān)閉ftpserver連接", sessionId.toString());
}
User user = session.getUser();
if(user!=null&&user.getName()!=null){
log.info("{}用戶名:{}關(guān)閉ftpserver連接.", sessionId.toString(), user.getName());
}
return super.onDisconnect(session);
}
/**
* 開(kāi)始上傳
*/
@Override
public FtpletResult onUploadStart(FtpSession session, FtpRequest request)
throws FtpException, IOException {
//獲取上傳文件的上傳路徑
String path = session.getUser().getHomeDirectory();
//自動(dòng)創(chuàng)建上傳路徑
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
//獲取上傳用戶
String name = session.getUser().getName();
//獲取上傳文件名
String filename = request.getArgument();
log.info("用戶:'{}',上傳文件到目錄:'{}',文件名稱為:'{}',狀態(tài):開(kāi)始上傳~", name, path, filename);
return super.onUploadEnd(session, request);
}
/**
* 上傳完成
*/
@Override
public 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("用戶:'{}',上傳文件到目錄:'{}',文件名稱為:'{},狀態(tài):成功!'", name, path, filename);
return super.onUploadStart(session, request);
}
@Override
public FtpletResult onDownloadStart(FtpSession session, FtpRequest request) throws FtpException, IOException {
return super.onDownloadStart(session, request);
}
@Override
public FtpletResult onDownloadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException {
return super.onDownloadEnd(session, request);
}
}以上步驟完成后,啟動(dòng)springboot。使用ftpclient工具嘗試連接配置文件里的8021控制端口,如以下圖所示,可以看到已經(jīng)連接成功。

到此這篇關(guān)于springboot快速搭建ftpserver服務(wù)端的文章就介紹到這了,更多相關(guān)springboot 搭建ftpserver服務(wù)端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Springboot-application.properties中文亂碼問(wèn)題
這篇文章主要介紹了解決Springboot-application.properties中文亂碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java設(shè)計(jì)模式之單例模式簡(jiǎn)介
這篇文章主要介紹了Java設(shè)計(jì)模式之單例模式簡(jiǎn)介,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)Java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
Mybatis主配置文件的properties標(biāo)簽詳解
這篇文章主要介紹了Mybatis主配置文件的properties標(biāo)簽,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
idea將maven項(xiàng)目改成Spring boot項(xiàng)目的方法步驟
這篇文章主要介紹了idea將maven項(xiàng)目改成Spring boot項(xiàng)目的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Java壓縮和解壓縮ZIP文件實(shí)戰(zhàn)案例
這篇文章主要給大家介紹了關(guān)于Java壓縮和解壓縮ZIP文件的相關(guān)資料,ZIP是一種較為常見(jiàn)的壓縮形式,最近項(xiàng)目中遇到了再Java中壓縮和解壓縮zip文件的需求,特此分享給大家,需要的朋友可以參考下2023-07-07
Java使用Filter實(shí)現(xiàn)登錄驗(yàn)證
本文主要介紹了Java使用Filter實(shí)現(xiàn)登錄驗(yàn)證,Filter類似于門(mén)衛(wèi),你在進(jìn)入之前門(mén)衛(wèi)需要盤(pán)查你,身份合法進(jìn)入,身份不合法攔截,感興趣的可以了解一下2023-11-11
Java DecimalFormat 保留小數(shù)位及四舍五入的陷阱介紹
這篇文章主要介紹了Java DecimalFormat 保留小數(shù)位及四舍五入的陷阱,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10

