java实现ftpServer
程序员文章站
2024-03-24 08:11:04
...
maven依赖
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
FtpServer.java ftp服务器的相关配置,用户,密码等
@Component
@Slf4j
public class FtpServer implements CommandLineRunner {
@Autowired
private LocalFtplet localFtplet;
@Autowired
private FtpServerFactory ftpServerFactory;
@Autowired
private ScheduledExecutorService scheduledExecutorService;
@Value("${ftp.server.port}")
private int serverPort;
@Value("${ftp.rootdir}")
private String ftpRootDir;
private static List<Authority> authorities = new ArrayList<>();
static {
authorities.add(new WritePermission());
}
@Autowired
private CameraManager cameraManager;
@Override
public void run(String... args) throws Exception {
ListenerFactory factory = new ListenerFactory();
//设置监听端口
factory.setPort(serverPort);
DataConnectionConfigurationFactory dataConnectionConfFactory = new DataConnectionConfigurationFactory();
dataConnectionConfFactory.setPassivePorts("10000-10500");
factory.setDataConnectionConfiguration(dataConnectionConfFactory.createDataConnectionConfiguration());
//替换默认监听
ftpServerFactory.addListener("default", factory.createListener());
UserManager userManager = ftpServerFactory.getUserManager();
//添加ftp用户
cameraManager.getAllCameraInfo().forEach(item -> {
try {
userManager.save(createFtpBaseUser(item.getSerialNo()));
} catch (FtpException e) {
e.printStackTrace();
}
});
Map<String, Ftplet> ftpLets = new HashMap<>();
ftpLets.put("ftpService", localFtplet);
ftpServerFactory.setFtplets(ftpLets);
org.apache.ftpserver.FtpServer server = ftpServerFactory.createServer();
server.start();
new FtpInitTask().init();
}
@EventListener
public void handlerCameraSerialNoChange(CameraSerialNoChangeEvent event) {
UserManager userManager = ftpServerFactory.getUserManager();
try {
if (CameraChangeType.DELETE.equals(event.getChangeType())) {
deleteFtpUser(userManager, event.getSerialNo());
} else if (CameraChangeType.UPDATE.equals(event.getChangeType())) {
updateFtpUser(userManager, event.getSerialNo());
}
} catch (FtpException e) {
log.error("修改ftp用户信息失败", e);
}
}
class FtpInitTask {
public void init() throws Exception {
updateUsersRootDir();
scheduledExecutorService.scheduleAtFixedRate(this::updateUsersRootDir, getInitialDelay(), 60 * 60 * 24, TimeUnit.SECONDS);
}
private void updateUsersRootDir() {
UserManager userManager = ftpServerFactory.getUserManager();
cameraManager.getAllCameraInfo().forEach(cameraInfo -> updateUserRootDir(userManager, cameraInfo));
}
public void updateUserRootDir(UserManager userManager, CameraInfo cameraInfo) {
try {
updateFtpUser(userManager, cameraInfo.getSerialNo());
} catch (FtpException e) {
log.error("修改ftp用户信息失败", e);
}
}
/**
* 获取第二天凌晨的时间戳
*
* @return
*/
private long getTomorrowOneOClockTime() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, 1);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTimeInMillis();
}
private long getInitialDelay() {
//延迟一秒执行,解决系统获取当前时间为昨天日期的问题
return (getTomorrowOneOClockTime() - System.currentTimeMillis()) / 1000 + 1;
}
}
private void updateFtpUser(UserManager userManager, String serialNo) throws FtpException {
deleteFtpUser(userManager, serialNo);
BaseUser baseUser = createFtpBaseUser(serialNo);
String rootdir = baseUser.getHomeDirectory();
String dir = PathUtils.filePathJoin(rootdir, TimeUtils.getNowTimeStr("yyyy-MM-dd"));
createDir(dir);
baseUser.setHomeDirectory(dir);
userManager.save(baseUser);
}
private void deleteFtpUser(UserManager userManager, String serialNo) {
try {
if (userManager.doesExist(serialNo)) {
userManager.delete(serialNo);
}
} catch (FtpException e) {
log.error("删除ftp用户失败:username{}", serialNo);
}
}
private BaseUser createFtpBaseUser(String serialNo) {
BaseUser user = new BaseUser();
user.setName(serialNo);
//密码 如果不设置密码就是匿名用户
user.setPassword(serialNo);
//用户主目录
user.setHomeDirectory(PathUtils.filePathJoin(ftpRootDir, serialNo));
user.setAuthorities(authorities);
return user;
}
//增加写权限
private void createDir(String dir) {
File folder = new File(dir);
if (!folder.exists() && !folder.isDirectory()) {
log.info("创建图片文件夹:{},结果:{}", dir, folder.mkdirs());
}
}
}
LocalFtplet.java 文件上传的各种回调
@Slf4j
@Component
public class LocalFtplet extends DefaultFtplet {
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
private FtpFileUploadTimeHandlerCenter ftpFileUploadTimeHandlerCenter;
@Override
public FtpletResult onUploadStart(FtpSession session, FtpRequest request)
throws FtpException, IOException {
//获取上传文件的上传路径
String path = session.getUser().getHomeDirectory();
//获取上传用户
String name = session.getUser().getName();
//获取上传文件名
String filename = request.getArgument();
log.info("用户:'{}',开始上传文件到目录:'{}',文件名称为:'{}',时间:{}", name, path, filename, TimeUtils.getNowTimeStr());
int startTimeRecordMapSize = ftpFileUploadTimeHandlerCenter.getStartTimeRecordMap().size();
if (startTimeRecordMapSize < 300) {
ftpFileUploadTimeHandlerCenter.putSessionStartTime(session.getSessionId().toString(), System.currentTimeMillis());
} else {
log.warn("积累了太多的开始时间未处理:startTimeRecordMap size: {}", startTimeRecordMapSize);
}
return super.onUploadStart(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();
log.info("用户:'{}',上传文件到目录结束:'{}',文件名称为:'{},时间:{}'", name, path, filename, TimeUtils.getNowTimeStr());
String sessionId = session.getSessionId().toString();
long uploadStartTime = getUploadStartTime(sessionId);
publisher.publishEvent(FileUploadEvent.builder()
.fileName(filename)
.path(path)
.sessionId(sessionId)
.ftpUser(name)
.uploadStartTime(uploadStartTime)
.uploadTakeTime(countUploadTakeTime(uploadStartTime))
.build());
publisher.publishEvent(new ThumbnailsImageSaveEvent(filename, path, ThumbnailsImageSaveTypeEnum.SOURCE_THUMBNAILS));
return super.onUploadEnd(session, request);
}
private Long countUploadTakeTime(long startUploadTime) {
if (startUploadTime == 0L) {
return 0L;
}
return System.currentTimeMillis() - startUploadTime;
}
private Long getUploadStartTime(String sessionId) {
return ftpFileUploadTimeHandlerCenter.getStartTimeRecord(sessionId)
.orElseGet(() -> {
log.warn("未找到文件开始上传时间");
return 0L;
});
}
}
推荐阅读
-
非poi实现word中导入pic图片代码示例 博客分类: word操作
-
activeMQBroker 编译错误Exception in thread “main“ java.lang.NoClassDefFoundError: com/fasterxml/jackson/
-
java实现ftpServer
-
计算某时间段内所有周的时间集合 博客分类: JAVA java日期计算日期工具
-
非poi实现word中导入pic图片代码示例 博客分类: word操作
-
Java 自动拆装箱
-
hashmap源码分析 博客分类: java javahashmap
-
java之路第一步:Markdown基础学习
-
使用hstore实现postgresql自定义聚合函数 博客分类: postgresql postgresqlhstore聚合函数
-
JAVA书籍推荐 博客分类: 工作日志 java编程设计模式企业应用ejb