最近项目需要在项目里内嵌一个ftp服务器,启动项目后可以用Filezila等客户端工具向服务器ftp推送文件
引入依赖
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.1.1</version>
</dependency>
InitFtpServer
ftp服务的启动器
package com.ruoyi.web.controller.tool.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.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* springboot启动时初始化ftpserver
*/
@Component
public class InitFtpServer implements CommandLineRunner {
public static final Logger log = LoggerFactory.getLogger(FtpServer.class);
@Autowired
private FtpServer server;
@Override
public void run(String... args) throws Exception {
try {
server.start();
log.info(">>>>>>>ftp start success ");
} catch (FtpException e) {
e.printStackTrace();
log.error(">>>>>>>ftp start error {}", e);
}
}
}
FtpConfig
ftp服务的配置类
package com.ruoyi.web.controller.tool.ftp;
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;
/**
* 配置类
*/
@Configuration
public class FtpConfig {
@Value("${ftp.port}")
private Integer ftpPort;
@Bean
public FtpServer createFtpServer(){
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
// ftp端口
factory.setPort(ftpPort);
/**
* 被动模式
*/
DataConnectionConfigurationFactory dataConnectionConfigurationFactory=new DataConnectionConfigurationFactory();
dataConnectionConfigurationFactory.setActiveEnabled(true);
dataConnectionConfigurationFactory.setIdleTime(60);
dataConnectionConfigurationFactory.setActiveLocalPort(2121);
dataConnectionConfigurationFactory.setPassiveAddress("0.0.0.0");
dataConnectionConfigurationFactory.setPassivePorts("2000-2222");
dataConnectionConfigurationFactory.setPassiveExternalAddress("127.0.0.1");
factory.setDataConnectionConfiguration(dataConnectionConfigurationFactory.createDataConnectionConfiguration());
// replace the default listener
serverFactory.addListener("default", factory.createListener());
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
try
{
ClassPathResource classPathResource = new ClassPathResource("users.properties");
userManagerFactory.setUrl(classPathResource.getURL());
}
catch (Exception e){
throw new RuntimeException("配置文件users.properties不存在");
}
userManagerFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor());
serverFactory.setUserManager(userManagerFactory.createUserManager());
Map<String, Ftplet> m = new HashMap<String, Ftplet>();
m.put("miaFtplet", new UploadListener());
serverFactory.setFtplets(m);
// start the server
FtpServer server = serverFactory.createServer();
return server;
}
}
UploadListener
ftp文件上传的监听器
如果有一个文件记录表,要记录ftp推送上来的文件,可在监听器里做配置
监听器无法通过autowirte注入bean,写一个bean工厂,从spring的上下文WebApplicationContext 中获取。
package com.ruoyi.web.controller.tool.ftp;
import org.apache.ftpserver.ftplet.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class UploadListener extends DefaultFtplet {
public static final Logger log= LoggerFactory.getLogger(UploadListener.class);
/**
*
* 开始上传
* Override this method to intercept uploads
* @param session The current {@link FtpSession}
* @param request The current {@link FtpRequest}
* @return The action for the container to take
* @throws FtpException
* @throws 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);
}
/**
* 上传完成
* Override this method to handle uploads after completion
* @param session The current {@link FtpSession}
* @param request The current {@link FtpRequest}
* @return The action for the container to take
* @throws FtpException
* @throws 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()){
System.out.println(file);
}
log.info("用户:'{}',上传文件到目录:'{}',文件名称为:'{},状态:成功!'", name, path, filename);
return super.onUploadStart(session, request);
}
@Override
public FtpletResult onDownloadStart(FtpSession session, FtpRequest request) throws FtpException, IOException {
//todo servies...
return super.onDownloadStart(session, request);
}
@Override
public FtpletResult onDownloadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException {
//todo servies...
return super.onDownloadEnd(session, request);
}
}
ftp的配置文件
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#��������һ��rmtfile�û���
#���� �����µ��û�
ftpserver.user.rmtfile.userpassword=r90ffzim87we
#��Ŀ¼����������Զ����Լ�����Ŀ¼
#ftpserver.user.rmtfile.homedirectory=E:\\myftp
#ftpserver.user.rmtfile.homedirectory=/home/data/ftp/
ftpserver.user.rmtfile.homedirectory=./myftp/
#��ǰ�û�����
ftpserver.user.rmtfile.enableflag=true
#�����ϴ�Ȩ��
ftpserver.user.rmtfile.writepermission=true
#����½�û���Ϊ20
ftpserver.user.rmtfile.maxloginnumber=9999
#ͬIP��½�û���Ϊ2
ftpserver.user.rmtfile.maxloginperip=9999
#����ʱ��Ϊ300��
ftpserver.user.rmtfile.idletime=300
#�ϴ���������Ϊ480000�ֽ�ÿ��
ftpserver.user.rmtfile.uploadrate=48000000
#������������Ϊ480000�ֽ�ÿ��
ftpserver.user.rmtfile.downloadrate=48000000
#�����û��������������(���������������û�����)
ftpserver.user.anonymous.userpassword=
#ftpserver.user.anonymous.homedirectory=C:\\myftp
ftpserver.user.anonymous.enableflag=false
# ftpserver.user.anonymous.writepermission=true
# ftpserver.user.anonymous.maxloginnumber=9999
# ftpserver.user.anonymous.maxloginperip=9999
# ftpserver.user.anonymous.idletime=300
# ftpserver.user.anonymous.uploadrate=4800
# ftpserver.user.anonymous.downloadrate=4800