引言
这里介绍
java
创建Ftp服务器
, 并且监测客户端上传文件后,读取文件的操作。使用hutool
创建Ftp客户端,使用ftplet-api
下的DefaultFtplet
进行文件监听。
这里有个小小的问题DefaultFtplet
监听器是ftp
依赖下的类,测试使用Hutool
下的Ftp
类,所以无法通过Ftp
指定文件夹上传,只能上传 创建Ftp 服务器
时 指定的文件夹
添加依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftplet-api</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.16</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
yml配置文件 及配置类
这里提供一种,引入
ftp服务器
账号密码的方式,当然也可以写死或者其他方式引入
yml配置文件 定义账号 密码 端口号
ftp-server:
port: 27 # 端口号
username: ftp
password: ftp
配置类
package com.esframework.project.kdzt.ftp.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* @author Administrator
*/
@Data
@Component
@Configuration
@ConfigurationProperties(prefix = "ftp-server")
public class FtpProperties {
private Integer port;
private String username;
private String password;
}
利用hutool代码 整合spring boot 创建 ftp服务端
配置监听器
package com.example.ftp.ftp2;
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;
/**
* ftp服务器侦听器
*
* @date 2023/06/29
*/
public class FtpServerListener extends DefaultFtplet {
public static final Logger log = LoggerFactory.getLogger(FtpServerListener.class);
/**
* 在连接* 开始连接@param session 会话
*
* @return {@link FtpletResult}
* @throws FtpException ftp例外
* @throws IOException ioexception
*/
@Override
public FtpletResult onConnect(FtpSession session) throws FtpException, IOException {
UUID sessionId = session.getSessionId();
if (sessionId != null) {
log.info("{}尝试登录ftpserver", sessionId);
}
User user = session.getUser();
if (user != null && user.getName() != null) {
assert sessionId != null;
log.info("{}尝试使用用户名:{},密码:{}登录ftpserver.", sessionId, user.getName(), user.getPassword());
}
return super.onConnect(session);
}
/**
* 在断开* 关闭连接@param session 会话
*
* @return {@link FtpletResult}
* @throws FtpException ftp例外
* @throws IOException ioexception
*/
@Override
public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException {
UUID sessionId = session.getSessionId();
User user = session.getUser();
if (sessionId != null) {
log.info("{}关闭ftpserver连接", sessionId);
}
if (user != null && user.getName() != null) {
assert sessionId != null;
log.info("{}用户名:{}关闭ftpserver连接.", sessionId, user.getName());
}
return super.onDisconnect(session);
}
/**
* 上传开始* 开始上传@param session 会话
*
* @param request 请求
* @return {@link FtpletResult}
* @throws FtpException ftp例外
* @throws IOException ioexception
*/
@Override
public 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);
}
/**
* 在上传* 上传完成@param session 会话
*
* @param request 请求
* @return {@link FtpletResult}
* @throws FtpException ftp例外
* @throws IOException ioexception
*/
@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()) {
// 读取文件
String filePath = String.format("%s\\%s", path, fileName);
log.info("用户:'{}',上传文件到目录:'{}',文件名称为:'{},状态:成功!'", 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);
}
}
使用 ApplicationRunner
启动服务时,创建 ftp
服务
package com.example.ftp.ftp2;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.ftp.SimpleFtpServer;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.List;
/**
* ftp服务器
*
* @author Administrator
* @date 2023/06/30
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class FtpServer implements ApplicationRunner {
private final FtpProperties ftpProperties;
@Override
public void run(ApplicationArguments args) throws Exception {
BaseUser user = new BaseUser();
user.setName(ftpProperties.getUsername());
user.setPassword(ftpProperties.getPassword());
// 配置上传的文件夹 没有就新建
File folder = FileUtil.file("folder");
if(!folder.exists()) {
boolean mkdir = folder.mkdir();
}
user.setHomeDirectory("D:\ftp");
user.setMaxIdleTime(0);
user.setEnabled(true);
//设置用户权限
List<Authority> authorities = Lists.newArrayList();
authorities.add(new WritePermission());
user.setAuthorities(authorities);
SimpleFtpServer simpleFtpServer = SimpleFtpServer.create().addUser(user).setPort(ftpProperties.getPort());
// 配置监听器
simpleFtpServer.addFtplet("folder", new FtpServerListener());
simpleFtpServer.start();
log.info("Ftp 开启=====》");
}
}
注意:
测试
使用 hutool 进行测试
注意
下面使用 public boolean upload(String destPath, File file)
这个方法时 destPath
会根据 Ftp Server
创建时 user的 setHomeDirectory
参数变化,
- 不设置
setHomeDirectory
参数时,destPath
写全部路径,但是监听器无法获取 上传文件的全路径。 - 设置
setHomeDirectory
参数时,destPath
填写/
就是setHomeDirectory
定义的文件夹
package com.example.ftp.ftp;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.ftp.Ftp;
import java.io.IOException;
public class FtpTest {
public static void main(String[] args) {
Ftp ftp1 = new Ftp("192.168.2.141",27, "ftp", "ftp");
try {
ftp1.upload("/", FileUtil.file("D:\\FlFile\\1234.txt"));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ftp1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}