springboot FTP服务器 上传&&下载示例demo
作者:互联网
最近项目上需要使用ftp服务器和第三方进行资源交互,于是写了个小demo记录下~
基础知识
FTP服务器
FTP(File Transfer Protocol)即文件传输协议,是一种基于TCP的协议,采用客户/服务器模式。通过FTP协议,用户可以在FTP服务器中进行文件的上传或下载等操作。虽然现在通过HTTP协议下载的站点有很多,但是由于FTP协议可以很好地控制用户数量和宽带的分配,快速方便地上传、下载文件,因此FTP已成为网络中文件上传和下载的首选服务器。同时,它也是一个应用程序,用户可以通过它把自己的计算机与世界各地所有运行FTP协议的服务器相连,访问服务器上的大量程序和信息。FTP服务的功能是实现完整文件的异地传输。(来自百度百科)
多级目录下创建文件
一直以为ftp服务器多级目录创建和java中目录创建一样,然而并不是滴~ 将文件hello.json上传至/home/upload/目录下步骤:
- 先使用FTPClient.changeWorkingDirectory("home"),判断home目录是否存在?若不存在则2
- 使用FTPClient.makeDirectory("home") 创建目录,同时使用FTPClient.changeWorkingDirectory("home")将ftp session指向home目录
- 使用FTPClient.changeWorkingDirectory("upload")判断upload目录是否存在?若不存在则4
- 使用FTPClient.makeDirectory("upload")创建目录,同时使用FTPClient.changeWorkingDirectory("upload")将ftp session指向upload目录
- 使用FTPClient.storeFile(fileName, is); 上传文件流is
FTP传输模式
对比方面 主动模式 被动模式 客户端 随机开放一个端口(1024以上) - 服务端 - 在本地随机开放一个端口(1024以上)实践出真知
引入依赖和加入配置
- pom.xml 中添加依赖
<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.6</version> </dependency>
- 在application.yml中添加ftp服务器配置(多环境则需要在application-dev/test/prod.yml中分别配置)
ftp: hostname: 172.16.1.1 port: 21 username: lizzy password: lizzy root-path: /upload/
定义配置bean
package com.lizzy.common.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import lombok.Data; @ConfigurationProperties(prefix = "ftp") @Data @Component public class FtpConfig { private String hostname; private Integer port; private String username; private String password; private String rootPath; }
定义FTP工具类
获取FTPClient,设置超时
private FTPClient getFTPClient() { FTPClient client = new FTPClient(); // 设置默认超时时间30s client.setDefaultTimeout(30000); // 设置链接超时时间 client.setConnectTimeout(30000); // 设置数据传输时间 client.setDataTimeout(30000); return client; }
上传
/** * 上传文件至FTP服务器 * @param config ftp服务器配置 * @param path 相对目录(不包含根目录) * @param fileName 文件名 * @param is 文件流 */ public static void upload(FtpConfig config, String path, String fileName, InputStream is) { FTPClient client = getFTPClient(); try { // 连接服务器 client.connect(config.getHostname(), config.getPort()); // 登录 client.login(config.getUsername(), config.getPassword()); int reply = client.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { // 连接失败 client.disconnect(); log.info("FTP服务器配置链接失败!请检查配置:{}", config.toString()); return ; } // 设置被动模式,开通一个端口来传输数据 client.enterLocalPassiveMode(); // 切换到上传目录 final String filePath = config.getRootPath() + path; if (!client.changeWorkingDirectory(filePath)) { // 目录不存在则创建 String[] dirs = filePath.split("/"); for (String dir : dirs) { if (StringUtils.isEmpty(dir)) { continue ; } if (!client.changeWorkingDirectory(dir)) { client.makeDirectory(dir); client.changeWorkingDirectory(dir); } } } // 设置被动模式,开通一个端口来传输数据 client.enterLocalPassiveMode(); //设置上传文件的类型为二进制类型 client.setFileType(FTP.BINARY_FILE_TYPE); client.storeFile(fileName, is); log.debug("文件{}成功上传至FTP服务器!", filePath + "/" + fileName); client.logout(); } catch (IOException e) { log.info("FTP服务器配置链接失败!错误:{}", e.getMessage()); e.printStackTrace(); } finally { try { is.close(); if (client.isConnected()) { client.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } }