FTP在docker容器中上傳失敗解決,改為被動模式
阿新 • • 發佈:2019-02-13
package com.mayocase.takeout.utils; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.mayocase.takeout.user.rest.UserLoginController; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; /** * Created by laiwr on 2018/5/18. */ @Component public class FtpUtils { private static Logger logger = LoggerFactory.getLogger(UserLoginController.class); @Autowired private FtpConfig ftpConfig; public FTPClient ftpClient = null; /** * 初始化連結檔案 */ public void initFtpClient() { ftpClient = new FTPClient(); ftpClient.setRemoteVerificationEnabled(false); //取消伺服器獲取自身Ip地址和提交的host進行匹配,否則當不一致時會報異常。 ftpClient.setControlEncoding("utf-8"); //在連線之前設定編碼型別為utf-8 try { ftpClient.setDataTimeout(1000*120); //設定傳輸超時時間為120秒 ftpClient.connect(ftpConfig.getHostname(), ftpConfig.getPort()); //連線ftp伺服器 ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword()); //登入ftp伺服器 int replyCode = ftpClient.getReplyCode(); //是否成功登入伺服器 if(!FTPReply.isPositiveCompletion(replyCode)){ logger.warn("【initFtpClient】: 登入伺服器失敗"); } logger.warn("【initFtpClient】: 使用帳戶:"+ftpConfig.getUsername()+"密碼:"+ftpConfig.getPassword()+"登入ftp伺服器:"+ftpConfig.getHostname()+":"+ftpConfig.getPort()); logger.warn("【initFtpClient】: 成功登入伺服器,被動模式主機:"+ftpClient.getPassiveHost()+":"+ftpClient.getPassivePort()); logger.warn("【initFtpClient】: 成功登入伺服器,主動模式主機:"+ftpClient.getRemoteAddress()+":"+ftpClient.getRemotePort()); logger.warn("【initFtpClient】: 成功登入伺服器,本地主機:"+ftpClient.getLocalAddress()+":"+ftpClient.getLocalPort()); logger.warn("【initFtpClient】: 成功登入伺服器,返回程式碼:"+ftpClient.getReplyCode()+",顯示狀態"+ftpClient.getStatus()); }catch (MalformedURLException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } /** * 上傳檔案 * @param pathname ftp服務儲存地址 * @param fileName 上傳到ftp的檔名 * @param inputStream 輸入檔案流 * @return */ public boolean uploadFile( String pathname, String fileName,InputStream inputStream){ boolean flag = false; try{ logger.warn("【uploadFile】: " + "開始上傳檔案"); initFtpClient(); ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE); //設定傳輸的模式為二進位制檔案型別傳輸 ftpClient.makeDirectory(pathname); //設定目錄 ftpClient.changeWorkingDirectory(pathname); //設定工作路徑 ftpClient.enterLocalPassiveMode(); //設定被動模式(FTP客戶端在docker容器內,需用被動模式) ftpClient.storeFile(fileName, inputStream); //上傳 logger.warn("【uploadFile】: " + "上傳檔案成功"); flag = true; return flag; }catch (Exception e) { logger.warn("【uploadFile】: " + "上傳檔案失敗"); e.printStackTrace(); return flag; }finally{ if(null != inputStream){ try { inputStream.close(); //關閉檔案流 } catch (IOException e) { e.printStackTrace(); } } if(ftpClient.isConnected()){ try{ ftpClient.logout(); //退出FTP ftpClient.disconnect(); //斷開連線 }catch(IOException e){ e.printStackTrace(); } } } } }