java 集成ftpServer
1.pom文件jar 包
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.1.1</version>
</dependency>
2.匿名开启
SimpleFtpServer
.create()
// 此目录必须存在
.addAnonymous("d:/test/ftp/")
.start();
此时就可以通过资源管理器访问:
ftp://localhost
- 自定义用户
BaseUser user = new BaseUser();
user.setName("username");
user.setPassword("123");
user.setHomeDirectory("d:/test/user/");
SimpleFtpServer
.create()
.addUser(user)
.start();
2 集成Spring BOOT
1.引入相关jar包
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25 </version>
</dependency>
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftplet-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.16</version>
</dependency>
hutool包,这里只是使用了日志功能 或者使用 log4j也是可以的 无所谓
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.21</version>
</dependency>
2 配置ftpserver
配置ftpserver,提供ftpserver的init()、start()、stop()方法。
下面代码是根据我开发情况进行修改过的 使用了hutool
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.setting.Setting;
import org.apache.ftpserver.DataConnectionConfigurationFactory;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
/**
* 正式服务
* 注意:被@Configuration标记的类会被加入ioc容器中,而且类中所有带 @Bean注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。
* ftp服务访问地址:
* ftp://localhost:21/
*/
@Component
public class LekangFtpServer {
private static final Log log = LogFactory.get();
private static FtpServer server;
//我们这里利用spring加载@Configuration的特性来完成ftp server的初始化
public LekangFtpServer() throws FtpException {
initFtp();
log.info("Apache ftp server is already instantiation complete!");
}
/**
* ftp server init
*/
public static void initFtp() throws FtpException {
//使用hutool读取FTP默认配置
Setting ftpinfo = new Setting("ftpserver.setting");
//获取端口
Integer port = ftpinfo.getStr("port")!=null?Integer.valueOf(ftpinfo.getStr("port")):null;
//被动模式端口
String passivePorts = ftpinfo.getStr("passivePorts");
//用户名称
String username = ftpinfo.getStr("username");
//用户密码
String password = ftpinfo.getStr("password");
//空闲时间
Integer idleTime =ftpinfo.getStr("idleTime")!=null?Integer.valueOf(ftpinfo.getStr("idleTime")):null;
//上传速率限制
Integer uploadrate =ftpinfo.getStr("uploadrate")!=null?Integer.valueOf(ftpinfo.getStr("uploadrate")):null;
//上传路径
String basedir = ftpinfo.getStr("basedir");
//ftpserver配置
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory listenerFactory = new ListenerFactory();
//设置服务端口
listenerFactory.setPort(port);
//设置被动模式数据上传的接口范围,云服务器需要开放对应区间的端口给客户端
DataConnectionConfigurationFactory dataConnectionConfFactory = new DataConnectionConfigurationFactory();
dataConnectionConfFactory.setPassivePorts(passivePorts);
listenerFactory.setDataConnectionConfiguration(dataConnectionConfFactory.createDataConnectionConfiguration());
//配置监听器
//Listener listener = listenerFactory.createListener();
//serverFactory.addListener("default", listener);
//增加SSL安全配置 --暂时不需要
//配置自定义用户
BaseUser lekang = new BaseUser();
lekang.setName(username);
lekang.setPassword(password);
lekang.setHomeDirectory(basedir);
lekang.setMaxIdleTime(idleTime);
//设置用户权限
List<Authority> authorities = new ArrayList<Authority>();
authorities.add(new WritePermission());
lekang.setAuthorities(authorities);
serverFactory.getUserManager().save(lekang);
//实例化FTP Server
server = serverFactory.createServer();
}
/**
* ftp server start
* @PostConstruct 跟随容器启动执行
*/
@PostConstruct
public static void start(){
try {
server.start();
log.info("FTP开启!");
}catch(FtpException e) {
e.printStackTrace();
}
}
/**
* ftp server stop
* @PreDestroy 跟随容器关闭执行
*/
@PreDestroy
public static void stop() {
server.stop();
log.info("FTP关闭!");
}
}
FTP客户端上传下载
这个代码是直接拉过来的 没做过修改
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import java.io.*;
public class FtpClientUtil {
// ftp服务器ip地址
private static String FTP_ADDRESS = "localhost";
// 端口号
private static int FTP_PORT = 3131;
// 用户名
private static String FTP_USERNAME = "bxl";
// 密码
private static String FTP_PASSWORD = "123456";
// 相对路径
private static String FTP_BASEPATH = "";
public static boolean uploadFile(String remoteFileName, InputStream input) {
boolean flag = false;
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("UTF-8");
try {
int reply;
ftp.connect(FTP_ADDRESS, FTP_PORT);// 连接FTP服务器
ftp.login(FTP_USERNAME, FTP_PASSWORD);// 登录
reply = ftp.getReplyCode();
System.out.println("登录ftp服务返回状态码为:" + reply);
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return flag;
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
//设置为被动模式
ftp.enterLocalPassiveMode();
ftp.makeDirectory(FTP_BASEPATH);
ftp.changeWorkingDirectory(FTP_BASEPATH);
//originFilePath就是上传文件的文件名,建议使用生成的唯一命名,中文命名最好做转码
boolean a = ftp.storeFile(remoteFileName, input);
// boolean a = ftp.storeFile(new String(remoteFileName.getBytes(),"iso-8859-1"),input);
System.out.println("要上传的原始文件名为:" + remoteFileName + ", 上传结果:" + a);
input.close();
ftp.logout();
flag = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return flag;
}
// public static Boolean uploadFile(String remoteFileName, InputStream inputStream, String ftpAddress, int ftpPort,
// String ftpName, String ftpPassWord, String ftpBasePath) {
// FTP_ADDRESS = ftpAddress;
// FTP_PORT = ftpPort;
// FTP_USERNAME = ftpName;
// FTP_PASSWORD = ftpPassWord;
// FTP_BASEPATH = ftpBasePath;
// uploadFile(remoteFileName,inputStream);
// return true;
// }
public static boolean deleteFile(String filename) {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
try {
// 连接FTP服务器
ftpClient.connect(FTP_ADDRESS, FTP_PORT);
// 登录FTP服务器
ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
// 验证FTP服务器是否登录成功
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return flag;
}
// 切换FTP目录
ftpClient.changeWorkingDirectory(FTP_BASEPATH);
ftpClient.dele(filename);
ftpClient.logout();
flag = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
} catch (IOException e) {
}
}
}
return flag;
}
public static boolean downloadFile(String filename, String localPath) {
boolean flag = false;
// FTPSClient ftpClient = new FTPSClient("TLS", true);
FTPClient ftpClient = new FTPClient();
try {
// 连接FTP服务器
ftpClient.connect(FTP_ADDRESS, FTP_PORT);
// 登录FTP服务器
ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
// 验证FTP服务器是否登录成功
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return flag;
}
// 切换FTP目录
ftpClient.changeWorkingDirectory(FTP_BASEPATH);
//此处为demo方法,正常应该到数据库中查询fileName
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles) {
if (filename.equalsIgnoreCase(file.getName())) {
File localFile = new File(localPath + "/" + file.getName());
OutputStream os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
os.close();
}
}
ftpClient.logout();
flag = true;
System.out.println("文件下载完成!!!");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
} catch (IOException e) {
}
}
}
return flag;
}
}
PS
1.参考文章
Java使用Apache FtpServer实现嵌入式FTP服务器
springboot整合apache ftpserver详细教程