package com.jzxs.transmissionmonitor.manager.ftp;
import com.jzxs.transmissionmonitor.utils.PathUtils;
import com.jzxs.transmissionmonitor.utils.TimeUtils;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.ftpserver.ConnectionConfigFactory;
import org.apache.ftpserver.DataConnectionConfigurationFactory;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Slf4j
public class FtpServer implements CommandLineRunner {
@Autowired
private LocalFtplet localFtplet;//ftp各事件的回调监听
private FtpServerFactory ftpServerFactory;
@Value("${ftp.server.port}")
private int serverPort;
@Getter
@Value("${ftp.rootdir}")
private String ftpRootDir;
private static List<Authority> authorities = new ArrayList<>();
static {
authorities.add(new WritePermission());
}
@Getter
private org.apache.ftpserver.FtpServer server;
@Override
public void run(String... args) throws Exception {
defaultFtpServerInit();
}
public void defaultFtpServerInit() throws FtpException {
ftpServerFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
//设置监听端口
factory.setPort(serverPort);
DataConnectionConfigurationFactory dataConnectionConfFactory = new DataConnectionConfigurationFactory();
dataConnectionConfFactory.setPassivePorts("10251-10500");
factory.setDataConnectionConfiguration(dataConnectionConfFactory.createDataConnectionConfiguration());
//替换默认监听
ftpServerFactory.addListener("default", factory.createListener());
ConnectionConfigFactory scf=new ConnectionConfigFactory();
scf.setMaxLogins(1000);
ftpServerFactory.setConnectionConfig(scf.createConnectionConfig());
UserManager userManager = ftpServerFactory.getUserManager();
//添加ftp用户
userManager.save(createUpgradeFtpUser());
Map<String, Ftplet> ftpLets = new HashMap<>();
ftpLets.put("ftpService", localFtplet);
ftpServerFactory.setFtplets(ftpLets);
server = ftpServerFactory.createServer();
server.start();
}
public BaseUser createUpgradeFtpUser() {
BaseUser user = new BaseUser();
/*user.setName(upgradeConfig.getUser());
user.setPassword(upgradeConfig.getPassword());
//用户主目录
user.setHomeDirectory(upgradeConfig.getPath());
user.setAuthorities(authorities);
user.setMaxIdleTime(10);*/
return user;
}
private void updateFtpUser(UserManager userManager, String serialNo) throws FtpException {
deleteFtpUser(userManager, serialNo);
BaseUser baseUser = createFtpBaseUser(serialNo);
String rootdir = baseUser.getHomeDirectory();
createDir(rootdir);
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, TimeUtils.getNowTimeStr("yyyy-MM-dd"), serialNo));
user.setAuthorities(authorities);
user.setMaxIdleTime(10);
log.warn("用户:{}主目录:{}", serialNo, user.getHomeDirectory());
return user;
}
private void createDir(String dir) {
File folder = new File(dir);
if (!folder.exists() && !folder.isDirectory()) {
log.info("创建图片文件夹:{},结果:{}", dir, folder.mkdirs());
}
}
private void ftpServerRestart() {
log.warn("ftp服务重启中...");
if (server != null && !server.isStopped()) {
try {
server.stop();
Thread.sleep(3000);
defaultFtpServerInit();
log.warn("ftp服务重启成功");
} catch (Exception e) {
log.error("重启ftpService失败", e);
}
}
}
}
package com.jzxs.transmissionmonitor.manager.ftp;
import com.jzxs.transmissionmonitor.utils.TimeUtils;
import org.apache.ftpserver.ftplet.*;
import org.apache.ftpserver.impl.DefaultFtpSession;
import org.apache.ftpserver.impl.FtpIoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.lang.reflect.Field;
@Component
public class LocalFtplet extends DefaultFtplet {
private Logger log = LoggerFactory.getLogger("ftpLog");
@Override
public FtpletResult onConnect(FtpSession session) throws FtpException, IOException {
log.warn("客户端地址:{}", session.getClientAddress());
return super.onConnect(session);
}
@Override
public FtpletResult onLogin(FtpSession session, FtpRequest request) throws FtpException, IOException {
try {
Class aClass = ((DefaultFtpSession)session).getClass();
Field lastReply = aClass.getDeclaredField("ioSession");
lastReply.setAccessible(true);
FtpIoSession o = (FtpIoSession)lastReply.get(session);
String message = o.getLastReply().getMessage();
log.warn("登录用户名:{},登录结果:{},错误:{}", request.getArgument(),session.getUser() != null,message);
} catch (Exception e) {
e.printStackTrace();
}
return super.onLogin(session, request);
}
@Override
public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException {
return super.beforeCommand(session, request);
}
@Override
public FtpletResult afterCommand(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException {
return super.afterCommand(session, request, reply);
}
@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());
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();
return super.onUploadEnd(session, request);
}
}