ftp服務器搭建(windows):
vsftpd簡介:
vsftpd是“very secure FTP daemon”的縮寫,是一個完全免費的、開放源代碼的ftp服務器軟件。
下載地址:
http://download.happymmall.com/FTPServer.rar
安裝啟動步驟:
1.下載解壓,點擊.exe文件,打開看到如下界面:
2.用戶名和密碼可以自己隨意設置,只要在登錄的時候用這個就可以了,共享目錄是你要共享出去的你本地的一個目錄,上傳下載也都在這個里面。
3.打開cmd,輸入ipconfig,查看你自己的Ipv4地址
4.在瀏覽器中輸入ftp://你的ip地址,彈出登錄框,登錄即可看到你的共享目錄中的內容。
實現ftp圖片上傳對接:
1.將ftp服務器需要的配置信息放入properties中,包括ip, user, pwd, 域名前綴。例如:
ftp.server.ip=211.69.197.245
ftp.user=cq
ftp.pass=ftp123
ftp.server.http.prefix=http://img.mall.com/
2.寫一個service,上傳圖片文件到ftp服務器,在這個service中,對path以及文件名做一定的處理,然后具體的上傳工作由調用FTPUtil來實現。此時運行后也就需要將ftp服務器開啟,才能正確連接並上傳。

1 @Service("iFileService") 2 public class FileServiceImpl implements IFileService{ 3 4 private Logger logger = LoggerFactory.getLogger(FileServiceImpl.class); 5 6 /** 7 * 上傳圖片文件到服務器 8 * @param file 要上傳的圖片文件 9 * @param path 上傳路徑 10 * @return 上傳成功后的文件名返回 11 */ 12 public String upload(MultipartFile file, String path) { 13 //獲取原始文件名 14 String fileName = file.getOriginalFilename(); 15 //獲取文件擴展名 16 //lastIndexOf:返回"."在fileName中最后一個匹配項的索引位置,即abc.jpg會返回.jpg 17 String fileExtensionName = fileName.substring(fileName.lastIndexOf(".") + 1); 18 //為了防止不同用戶上傳圖片時,兩張圖片的文件名完全相同導致覆蓋的情況,這里對文件名加上UUID防重復 19 String uploadFileName = UUID.randomUUID().toString() + "." + fileExtensionName; 20 //打印日志,通過{}進行占位,也就是一個占位符對應后面的一個數據,類似於c里面的printf("%c",h); 21 logger.info("開始上傳文件,上傳文件的文件名:{},上傳的路徑:{},新文件名:{}", fileName, path, uploadFileName); 22 23 //創建上傳路徑目錄的文件對象 24 File fileDir = new File(path); 25 if(!fileDir.exists()) { 26 //如果不存在 27 //賦予這個文件fileDir可寫 28 fileDir.setWritable(true); 29 //創建文件 30 //mkdir():當前級別 31 //mkdirs():如果上傳的文件所在的文件是/a,/b,/c等,直接傳到服務器上時,這些文件夾都沒有,用mkdirs()就可以自動創建 32 fileDir.mkdirs(); 33 } 34 File targetFile = new File(path, uploadFileName); 35 36 try { 37 file.transferTo(targetFile); 38 //將targetFile上傳到我們的ftp服務器上 39 FTPUtil.uploadFile(Lists.newArrayList(targetFile)); 40 //已經上 傳到ftp服務器上,刪除upload下面的文件 41 targetFile.delete(); 42 } catch (IOException e) { 43 logger.error("上傳文件異常", e); 44 return null; 45 } 46 return targetFile.getName(); 47 } 48 49 }
3.寫一個工具類FTPUtil,專門做圖片上傳的工作,在這個工具類中,從properties配置文件中拿到ip,user,pwd,在連接到ftp服務器后,用FTPClient做上傳工作。

1 public class FTPUtil { 2 3 private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class); 4 5 //根據key拿到value值 6 private static String ftpIp = PropertiesUtil.getProperty("ftp.server.ip"); 7 private static String ftpUser = PropertiesUtil.getProperty("ftp.user"); 8 private static String ftpPass = PropertiesUtil.getProperty("ftp.pass"); 9 10 //構造器 11 public FTPUtil(String ip,int port,String user,String pwd){ 12 this.ip = ip; 13 this.port = port; 14 this.user = user; 15 this.pwd = pwd; 16 } 17 //public開放方法 18 public static boolean uploadFile(List<File> fileList) throws IOException { 19 FTPUtil ftpUtil = new FTPUtil(ftpIp,21,ftpUser,ftpPass); 20 logger.info("開始連接ftp服務器"); 21 //remotePath是"img",也就是傳到ftp文件夾下面的img這個文件夾下 22 boolean result = ftpUtil.uploadFile("img",fileList); 23 logger.info("ftp服務器,結束上傳,上傳結果:{}", result); 24 return result; 25 } 26 //上傳的具體邏輯 27 //remotePath:遠程路徑,ftp服務器上的相對路徑,上傳到ftp服務器上,ftp服務器是一個文件夾,如果需要上傳到這個文件夾下的一個文件夾的話,就需要用到remotePath 28 private boolean uploadFile(String remotePath,List<File> fileList) throws IOException { 29 boolean uploaded = true; 30 FileInputStream fis = null; 31 //連接FTP服務器 32 if(connectServer(this.ip,this.port,this.user,this.pwd)){ 33 try { 34 //更改工作目錄,將remotePath傳入,如果是null,則不需要切換 35 ftpClient.changeWorkingDirectory(remotePath); 36 //設置緩沖區 37 ftpClient.setBufferSize(1024); 38 //設置encoding編碼 39 ftpClient.setControlEncoding("UTF-8"); 40 //設置文件類型為二進制類型,防止亂碼 41 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 42 //打開本地的ftp的被動模式 43 ftpClient.enterLocalPassiveMode(); 44 for(File fileItem : fileList){ 45 fis = new FileInputStream(fileItem); 46 //將文件存入ftpClient 47 ftpClient.storeFile(fileItem.getName(),fis); 48 } 49 50 } catch (IOException e) { 51 logger.error("上傳文件異常",e); 52 uploaded = false; 53 e.printStackTrace(); 54 } finally { 55 //關閉ftpClient 56 fis.close(); 57 ftpClient.disconnect(); 58 } 59 } 60 return uploaded; 61 } 62 //連接ftp服務器 63 private boolean connectServer(String ip,int port,String user,String pwd){ 64 65 boolean isSuccess = false; 66 ftpClient = new FTPClient(); 67 try { 68 //ftp服務器的ip 69 ftpClient.connect(ip); 70 //驗證ftp服務器用戶驗證是否通過 71 isSuccess = ftpClient.login(user,pwd); 72 } catch (IOException e) { 73 logger.error("連接FTP服務器異常",e); 74 } 75 return isSuccess; 76 } 77 78 private String ip; 79 private int port; 80 private String user; 81 private String pwd; 82 //使用FTPClient上傳下載 83 private FTPClient ftpClient; 84 85 public String getIp() { 86 return ip; 87 } 88 89 public void setIp(String ip) { 90 this.ip = ip; 91 } 92 93 public int getPort() { 94 return port; 95 } 96 97 public void setPort(int port) { 98 this.port = port; 99 } 100 101 public String getUser() { 102 return user; 103 } 104 105 public void setUser(String user) { 106 this.user = user; 107 } 108 109 public String getPwd() { 110 return pwd; 111 } 112 113 public void setPwd(String pwd) { 114 this.pwd = pwd; 115 } 116 117 public FTPClient getFtpClient() { 118 return ftpClient; 119 } 120 121 public void setFtpClient(FTPClient ftpClient) { 122 this.ftpClient = ftpClient; 123 } 124 }
4.提供給controller:

1 String path = request.getSession().getServletContext().getRealPath("upload"); 2 String targetFileName = iFileService.upload(file, path); 3 String url = PropertiesUtil.getProperty("ftp.server.http.prefix") + targetFileName; 4 Map fileMap = Maps.newHashMap(); 5 fileMap.put("uri", targetFileName); 6 fileMap.put("url", url); 7 return ServerResponse.createBySuccess(fileMap);
5.在開啟ftp服務器后,還需要開啟nginx,才能利用nginx反向代理,定位到http://img.mall.com/...