前言:最近在做一个app,负责写后台接口,客户那边给了一个FTP的账号密码过来,服务器上面放了一堆的PDF文件,让我们这边自己从上面拿,项目是spriongboot的,做个记录供以后参考。
一、application.yml文件里面配置FTP的相关参数,以便于后面更改相关参数,而不用去改具体的方法参数
ftp: #FTP的地址 ftpHost: 192.168.42.18 #FTP的端口 ftpPort: 21 #连接FTP的账号 ftpUserName: **** #账号密码 ftpPassword: **** #访问FTP的路径 ftpRemotePath: / #本地下载路径 ftpLocalPath: D:/
二、准备一个工具类,用于从application.yml文件读取FTP的相关配置
1 package com.example.springboot.utils; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.yaml.snakeyaml.Yaml; 6 7 import java.io.*; 8 import java.util.HashMap; 9 import java.util.Map; 10 11 import static java.util.Objects.isNull; 12 13 /** 14 * 工具类,从application.yml获取ftp相关参数 15 * 16 * @Author: yaodengyan 17 * @Date: 2019/11/7 18 * @Version: 1.0 19 */ 20 public class YmlUtils { 21 private static final Logger log = LoggerFactory.getLogger(YmlUtils.class); 22 23 private static String NAME = "application.yml"; 24 25 /** 空字符串 */ 26 private static final String NULLSTR = ""; 27 28 /** 29 * 当前对象实例 30 */ 31 private static YmlUtils ymlUtils; 32 33 /** 34 * 保存全局属性值 35 */ 36 private static Map<String, String> map = new HashMap<String, String>(); 37 38 private YmlUtils() 39 { 40 } 41 42 /** 43 * 静态工厂方法 44 */ 45 public static synchronized YmlUtils getInstance() 46 { 47 if (ymlUtils == null) 48 { 49 ymlUtils = new YmlUtils(); 50 } 51 return ymlUtils; 52 } 53 54 /** 55 * 获取配置 56 */ 57 public static String getConfig(String key) 58 { 59 String value = map.get(key); 60 if (value == null) 61 { 62 Map<?, ?> yamlMap = null; 63 yamlMap = loadYaml(NAME); 64 value = String.valueOf(getProperty(yamlMap, key)); 65 map.put(key, value != null ? value : ""); 66 } 67 return value; 68 } 69 70 public static Map<?, ?> loadYaml(String fileName) 71 { 72 InputStream in = YmlUtils.class.getClassLoader().getResourceAsStream(fileName); 73 if(isEmpty(fileName)){ 74 return null; 75 }else { 76 77 return new Yaml().load(in); 78 } 79 } 80 81 /** 82 * * 判断一个字符串是否为非空串 83 * 84 * @param str String 85 * @return true:非空串 false:空串 86 */ 87 public static boolean isEmpty(String str) 88 { 89 Boolean flag = isNull(str) || NULLSTR.equals(str.trim()); 90 return flag; 91 } 92 93 public static Object getProperty(Map<?, ?> map, Object qualifiedKey) 94 { 95 if (map != null && !map.isEmpty() && qualifiedKey != null) 96 { 97 String input = String.valueOf(qualifiedKey); 98 if (!"".equals(input)) 99 { 100 if (input.contains(".")) 101 { 102 int index = input.indexOf("."); 103 String left = input.substring(0, index); 104 String right = input.substring(index + 1, input.length()); 105 return getProperty((Map<?, ?>) map.get(left), right); 106 } 107 else if (map.containsKey(input)) 108 { 109 return map.get(input); 110 } 111 else 112 { 113 return null; 114 } 115 } 116 } 117 return null; 118 } 119 120 /** 121 * 获取参数不为空值 122 * 123 * @param value defaultValue 要判断的value 124 * @return value 返回值 125 */ 126 public static <T> T nvl(T value, T defaultValue) 127 { 128 return value != null ? value : defaultValue; 129 } 130 131 /** 132 * 获取FTP的地址 133 */ 134 public static String getFtpHost() 135 { 136 return nvl(getConfig("ftp.ftpHost"), ""); 137 } 138 139 /** 140 * 获取FTP的端口 141 */ 142 public static String getFtpPort() 143 { 144 return nvl(getConfig("ftp.ftpPort"), ""); 145 } 146 /** 147 * 获取连接FTP的账号 148 */ 149 public static String getFtpUserName() 150 { 151 return nvl(getConfig("ftp.ftpUserName"), ""); 152 } 153 /** 154 * 获取账号密码 155 */ 156 public static String getFtpPassword() 157 { 158 return nvl(getConfig("ftp.ftpPassword"), ""); 159 } 160 /** 161 * 获取访问FTP的路径 162 */ 163 public static String getFtpRemotePath() 164 { 165 return nvl(getConfig("ftp.ftpRemotePath"), ""); 166 } 167 /** 168 * 获取本地下载路径 169 */ 170 public static String getFtpLocalPath() 171 { 172 return nvl(getConfig("ftp.ftpLocalPath"), ""); 173 } 174 }
注意,这里需要引入的yml解析器的依赖
<!-- yml解析器 --> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> </dependency>
三、编写连接FTP工具类,用于连接FTP服务器
在项目pom.xml引入两个依赖包,一个是连接ftp需要的,另一个是作为打印日志需要的lombok
<!--FTP--> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.6</version> </dependency> <!--日志--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.6</version> </dependency>
下面就是连接ftp的工具类
1 package com.example.springboot.utils; 2 3 import lombok.extern.slf4j.Slf4j; 4 import org.apache.commons.net.ftp.FTPClient; 5 import org.apache.commons.net.ftp.FTPReply; 6 7 import java.io.IOException; 8 import java.net.SocketException; 9 10 /** 11 * 连接ftp服务器工具类 12 * 13 * @Author: yaodengyan 14 * @Date: 2019/11/7 15 * @Version: 1.0 16 */ 17 @Slf4j 18 public class FtpUtils { 19 public static FTPClient getFTPClient() { 20 FTPClient ftpClient = new FTPClient(); 21 try { 22 ftpClient = new FTPClient(); 23 ftpClient.connect(YmlUtils.getFtpHost(), Integer.valueOf(YmlUtils.getFtpPort()));// 连接FTP服务器 24 ftpClient.login(YmlUtils.getFtpUserName(), YmlUtils.getFtpPassword());// 登陆FTP服务器 25 if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { 26 log.error("未连接到FTP,用户名或密码错误。{}"); 27 ftpClient.disconnect(); 28 } else { 29 log.info("FTP连接成功{}"); 30 } 31 } catch (SocketException e) { 32 e.printStackTrace(); 33 log.error("FTP连接失败"); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 log.error("FTP的端口错误,请正确配置。"); 37 } 38 return ftpClient; 39 } 40 }
四、编写下载类实现从ftp服务器下载
1 package com.example.springboot.utils; 2 3 import lombok.extern.slf4j.Slf4j; 4 import org.apache.commons.net.ftp.FTPClient; 5 6 import java.io.*; 7 import java.net.SocketException; 8 9 /** 10 * ftp文件下载类 11 * 12 * @Author: yaodengyan 13 * @Date: 2019/11/7 14 * @Version: 1.0 15 */ 16 @Slf4j 17 public class DowdFile { 18 public static void downloadFile(String fileName) throws IOException { 19 FTPClient ftpClient = null; 20 OutputStream os = null; 21 try { 22 ftpClient = FtpUtils.getFTPClient(); 23 ftpClient.setControlEncoding("UTF-8"); // 中文支持 24 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 25 ftpClient.enterLocalPassiveMode(); 26 27 Boolean changeDirectory = ftpClient.changeWorkingDirectory(YmlUtils.getFtpRemotePath());//切换到ftp的目标路径 28 if (!changeDirectory) { 29 throw new RuntimeException("切换目录失败"); 30 } 31 File localFile = new File(YmlUtils.getFtpLocalPath() + File.separatorChar + fileName); 32 os = new FileOutputStream(localFile); 33 34 ftpClient.retrieveFile(fileName, os);//开始下载 35 log.info("文件下载成功"); 36 } catch (FileNotFoundException e) { 37 log.error("没有找到" + YmlUtils.getFtpRemotePath() + "文件"); 38 e.printStackTrace(); 39 } catch (SocketException e) { 40 log.error("连接FTP失败."); 41 e.printStackTrace(); 42 } catch (IOException e) { 43 e.printStackTrace(); 44 log.error("文件读取错误。"); 45 e.printStackTrace(); 46 }finally { 47 os.close(); 48 ftpClient.disconnect(); 49 log.info("FTP连接断开"); 50 } 51 } 52 }
五、编写上传文件到ftp服务器类
1 package com.example.springboot.utils; 2 3 import lombok.extern.slf4j.Slf4j; 4 import org.apache.commons.net.ftp.FTP; 5 import org.apache.commons.net.ftp.FTPClient; 6 7 import java.io.File; 8 import java.io.FileInputStream; 9 import java.io.FileNotFoundException; 10 import java.io.IOException; 11 12 /** 13 * 类说明 14 * 15 * @Author: yaodengyan 16 * @Date: 2019/11/7 17 * @Version: 1.0 18 */ 19 @Slf4j 20 public class UploadFile { 21 public static void uploadFile(String fileName) throws IOException { 22 FTPClient ftp = null; 23 FileInputStream input = new FileInputStream(new File(YmlUtils.getFtpLocalPath()+ File.separatorChar+fileName)); 24 try { 25 ftp = FtpUtils.getFTPClient(); 26 log.info("连接FTP成功!"); 27 ftp.changeWorkingDirectory(YmlUtils.getFtpRemotePath()); 28 ftp.setFileType(FTP.BINARY_FILE_TYPE); 29 fileName = new String(fileName.getBytes("GBK"),"iso-8859-1"); 30 ftp.storeFile(fileName, input); 31 log.info("上传成功{}"); 32 } catch (Exception e) { 33 e.printStackTrace(); 34 log.error("文件上传失败{}"); 35 }finally { 36 input.close(); 37 ftp.disconnect(); 38 log.info("FTP连接断开{}"); 39 } 40 } 41 42 public static void main(String[] args) throws IOException { 43 uploadFile("test.txt"); 44 } 45 }
六、测试结果
获取连接
文件下载
在我的D盘可以看到下载的文件:
文件上传:
ftp服务器上面:
七:总结
1.ftp的配置应当写在配置类,方便以后修改。
2.上传下载都是在获得ftp连接的基础上,获得连接也是最重要的一步。
后话:demo是学习一直知识点最好的方式!