基於spring boot ftp檔案上傳
阿新 • • 發佈:2019-01-30
對ftp檔案上傳將行封裝,實現連線的單例模式,完成執行緒安全的改進,ftp檔案上傳下載失敗的重試。
application.yml配置檔案
ftp: ip: 127.0.0.1 port: 21 username: admin password: admin downloadSleep: 100 #檔案下載失敗下次超時重試時間 downloadRetry: 10 #檔案下載失敗重試次數 uploadSleep: 100 #檔案上傳失敗下次超時重試時間 uploadRettry: 10 #檔案上傳失敗重試次數
FTPClientUtils.java
包含ftp檔案上傳的一些基本方法,單個上傳,批量下載,單個檔案下載
/** * FTP檔案上傳下載工具類 * @author 奇點_ * */ @Component @ConfigurationProperties(prefix = "ftp") public class FTPClientUtils { private static int downloadSleep; private static int downloadRetry; private static int uploadSleep; private static int uploadRettry; private static Logger LOGGER = LoggerFactory.getLogger(FTPClientUtils.class); /** * * @param ftpPath 上傳到ftp的路徑 * @param file 上傳到ftp的檔案物件 * @return boolean true上傳檔案成功 false 上傳檔案失敗 */ public static boolean doUpLoad(String ftpPath,File file){ boolean result=false; Integer i = 0; while(!result){ FTPClient client = FTPConnectionFactory.getInstance().makeConnection(); try { try { client.changeDirectory(ftpPath); } catch (Exception e) { LOGGER.error("ftp檔案目錄不存在:"+ftpPath); } client.upload(file); if(i>0){ LOGGER.info("ftp重試檔案上傳成功,ftp路徑:"+ftpPath+",檔名稱:"+file.getName()); }else{ LOGGER.info("ftp檔案上傳成功,ftp路徑為"+ftpPath+",檔名稱:"+file.getName()); } result = true; }catch (Exception e) { i++; LOGGER.error("ftp檔案上傳失敗,重試中。。。第"+i+"次,錯誤資訊"+e.getMessage()); if(i>uploadRettry){ LOGGER.error("ftp檔案上傳失敗,超過重試次數結束重試,錯誤資訊"+e.getMessage()); return result; } try { TimeUnit.MILLISECONDS.sleep(uploadSleep); } catch (InterruptedException e1) { e1.printStackTrace(); } } } return result; } /** * * @param ftpPath 要下載的檔案在ftp中的路徑 * @param fileName 要下載的檔名稱 * @param localPath 檔案要下載的路徑 * @return false 下載失敗 true 下載成功 */ public static boolean doDownLoad(String ftpPath,String fileName,String localPath){ boolean result=false; Integer i = 0; while(!result){ FTPClient client = FTPConnectionFactory.getInstance().makeConnection(); try { client.changeDirectory(ftpPath); client.download(fileName, new File(localPath+"/"+fileName)); if(i>0){ LOGGER.info("ftp檔案重試下載成功,ftp地址:"+ftpPath+",檔名稱:"+fileName+"本地檔案地址:"+localPath); }else{ LOGGER.info("ftp檔案下載成功,ftp地址:"+ftpPath+",檔名稱:"+fileName+"本地檔案地址:"+localPath); } result = true; }catch (Exception e) { i++; LOGGER.error("ftp檔案下載失敗,重試中。。。第"+i+"次,錯誤資訊ftp地址:"+ftpPath+",檔名稱:"+fileName+"本地檔案地址:"+localPath+e.getMessage()); if(i>downloadRetry){ LOGGER.error("ftp檔案下載失敗,超過重試次數結束重試,錯誤資訊ftp地址:"+ftpPath+",檔名稱:"+fileName+"本地檔案地址:"+localPath+e.getMessage()); return result; } try { TimeUnit.MILLISECONDS.sleep(downloadSleep); } catch (InterruptedException e1) { e1.printStackTrace(); } } } return result; } /** * * @param ftpPath 下載該目錄下的所有檔案,不包括資料夾 * @param localPath 下載到本地的目錄 * @return true 下載成功 false 下載失敗 */ public static boolean doDownLoad(String ftpPath,String localPath){ boolean result=false; FTPClient client = FTPConnectionFactory.getInstance().makeConnection(); try { client.changeDirectory(ftpPath); FTPFile[] fileNames = client.list(); for (FTPFile ftpFile : fileNames) { if(ftpFile.getType()==FTPFile.TYPE_FILE){ try { doDownLoad(ftpPath,ftpFile.getName(),localPath); } catch (Exception e) { } } } result = true; }catch (Exception e) { LOGGER.error("ftp檔案批量下載失敗,錯誤資訊"+e.getMessage()); } return result; } /** * 判斷一個FTP路徑是否存在,如果存在返回型別(FTPFile.TYPE_DIRECTORY=1、FTPFile.TYPE_FILE=0、FTPFile.TYPE_LINK=2) * 如果檔案不存在,則返回一個-1 * @param ftpPath FTP檔案或資料夾路徑 * @return 存在時候返回型別值(檔案0,資料夾1,連結2),不存在則返回-1 */ public static int isExist(String ftpPath){ FTPClient client = FTPConnectionFactory.getInstance().makeConnection(); FTPFile[] list = null; try { list = client.list(ftpPath); } catch (Exception e) { return -1; } if (list.length > 1) return FTPFile.TYPE_DIRECTORY; else if (list.length == 1) { FTPFile f = list[0]; if (f.getType() == FTPFile.TYPE_DIRECTORY) return FTPFile.TYPE_DIRECTORY; String _path = ftpPath +File.separator+ f.getName(); try { int y = client.list(_path).length; if (y == 1) return FTPFile.TYPE_DIRECTORY; else return FTPFile.TYPE_FILE; } catch (Exception e) { return -1; } } else { try { client.changeDirectory(ftpPath); return FTPFile.TYPE_DIRECTORY; } catch (Exception e) { return -1; } } } /** * * @param ftpPath 遞迴下載該目錄下的所有檔案。 * @param localPath 下載到本地的目錄 * @return true 下載成功 false 下載失敗 */ public synchronized static boolean doDownLoadAll(String ftpPath,String localPath){ boolean result=false; FTPClient client = FTPConnectionFactory.getInstance().makeConnection(); try { client.changeDirectory(ftpPath); FTPFile[] fileNames = client.list(); for (FTPFile ftpFile : fileNames) { if(ftpFile.getType()==FTPFile.TYPE_FILE){ try { doDownLoad(ftpPath, localPath); } catch (Exception e) { } } if(ftpFile.getType()==FTPFile.TYPE_DIRECTORY){ String path = localPath+"/"+ftpFile.getName(); File file = new File(path); if(!file.exists()){ file.mkdirs(); } doDownLoadAll(ftpPath+"/"+ftpFile.getName(), path); } } result = true; }catch (Exception e) { LOGGER.error("ftp檔案批量下載失敗,錯誤資訊"+e.getMessage()); } return result; } /** * * @param ftpPath ftp的檔案路徑 * @param localPath 檔案下載到的本地路徑 * @param ftpPathBak * @param isDeleteFile 下載後是否刪除檔案,傳入true or false * @param isBakFile * @return */ public static boolean doDownLoad(String ftpPath, String localPath, String ftpPathBak, String isDeleteFile, String isBakFile) { boolean result=false; Integer k = 0; while(!result){ FTPClient client = FTPConnectionFactory.getInstance().makeConnection(); try { client.changeDirectory(ftpPath); String[] fileNames = client.listNames(); for (int i = 0; i < fileNames.length; i++) { File file = new File(localPath+ fileNames[i]); client.download(fileNames[i], file); if (isBakFile.equals("true")){ client.rename(fileNames[i], ftpPathBak+fileNames[i]); } if (isDeleteFile.equals("true")){ client.deleteFile(fileNames[i]); } } if(k>0){ LOGGER.info("ftp檔案重試下載成功,ftp地址:"+ftpPath+",本地檔案地址:"+localPath); }else{ LOGGER.info("ftp檔案下載成功,ftp地址:"+ftpPath+"本地檔案地址:"+localPath); } result = true; } catch (Exception e) { k++; LOGGER.error("ftp檔案下載失敗,重試中。。。第"+k+"次,錯誤資訊"+e.getMessage()); if(k>downloadRetry){ return result; } try { TimeUnit.MILLISECONDS.sleep(downloadSleep); } catch (InterruptedException e1) { e1.printStackTrace(); } } } return result; } public static int getDownloadSleep() { return downloadSleep; } public static void setDownloadSleep(int downloadSleep) { FTPClientUtils.downloadSleep = downloadSleep; } public static int getDownloadRetry() { return downloadRetry; } public static void setDownloadRetry(int downloadRetry) { FTPClientUtils.downloadRetry = downloadRetry; } public static int getUploadSleep() { return uploadSleep; } public static void setUploadSleep(int uploadSleep) { FTPClientUtils.uploadSleep = uploadSleep; } public static int getUploadRettry() { return uploadRettry; } public static void setUploadRettry(int uploadRettry) { FTPClientUtils.uploadRettry = uploadRettry; } }
SFTPConnectionFactory.java
是生成sftp上傳物件的工場類
@Component @ConfigurationProperties(prefix = "ftp") public class FTPConnectionFactory { private static Logger LOGGER = LoggerFactory.getLogger(FTPClientUtils.class); /** FTP ip地址*/ private static String ip; /** FTP 埠號*/ private static int port; /** FTP 設定字符集*/ private static String charset; /** FTP 使用者名稱*/ private static String username; /** FTP 密碼*/ private static String password; private static final FTPConnectionFactory factory = new FTPConnectionFactory(); private FTPClient client; private FTPConnectionFactory(){ } public static FTPConnectionFactory getInstance(){ return factory; } synchronized public FTPClient makeConnection(){ if(client==null||!client.isConnected()){ try { client = new FTPClient(); client.connect(ip, port); client.setCharset(charset); client.login(username, password); } catch (Exception e) { LOGGER.error("ftp登入失敗,檢測登入ip,埠號,使用者名稱密碼是否正確,錯誤資訊為"+e.getMessage()); } LOGGER.info("ftp伺服器連線成功"); } return client; } /** * 關閉連線 server */ public void logout(){ if (client != null) { if (client.isConnected()) { try { client.disconnect(false); } catch (Exception e) { LOGGER.error("ftp連線斷開失敗,錯誤資訊"+e.getMessage()); }; } } } public static String getIp() { return ip; } public static void setIp(String ip) { FTPConnectionFactory.ip = ip; } public static int getPort() { return port; } public static void setPort(int port) { FTPConnectionFactory.port = port; } public static String getCharset() { return charset; } public static void setCharset(String charset) { FTPConnectionFactory.charset = charset; } public static String getUsername() { return username; } public static void setUsername(String username) { FTPConnectionFactory.username = username; } public static String getPassword() { return password; } public static void setPassword(String password) { FTPConnectionFactory.password = password; } }
pom.xml 依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>fakepath</groupId>
<artifactId>ftp4j</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>