springboot開發環境下搭建ftp+nginx圖片服務器以及其他文件的存儲

一、在搭建一個ftp服務器用於存儲文件

二、下載nginx,安裝完成後更改配置文件

server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }
		
		location ~ \.(gif|jpg|jpeg|png|bmp|swf)$ {   //設置圖片的格式
            root   D:/cateringFTP;     //ftp跟目錄
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

三、上傳文件到ftp

依賴

<!--ftp文件上傳-->
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
        </dependency>

FtpUtil如下

/**
 * 
 */
package shqn.sthj.modules.catering.utils;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
/**
 * @author hxl
 * @date 2019年10月31日
 * FtpUtil.java
 */
@Component
public class FtpUtil {

    Logger logger = Logger.getLogger(getClass());
    private String LOCAL_CHARSET = "GBK";

    //ftp服務器地址
    String hostname = "192.168.2.119";
    
    //ftp服務器端口
    int port = 22;

    //ftp登錄賬號
    String username = "catering";

    //ftp登錄密碼
    String password = "catering";

    //ftp保存目錄
    String basePath = "";

    /**
     * 初始化ftp服務器
     */
    public FTPClient getFtpClient() {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("utf-8");

        try {
            ftpClient.setDataTimeout(1000 * 120);//設置連接超時時間
            logger.info("connecting...ftp服務器:" + hostname + ":" + port);
            ftpClient.connect(hostname,port); // 連接ftp服務器
            ftpClient.login(username, password); // 登錄ftp服務器
            int replyCode = ftpClient.getReplyCode(); // 是否成功登錄服務器
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
                    "OPTS UTF8", "ON"))) {      // 開啓服務器對UTF-8的支持,如果服務器支持就用UTF-8編碼,否則就使用本地編碼(GBK).
                LOCAL_CHARSET = "UTF-8";
            }
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                logger.error("connect failed...ftp服務器:" + hostname + ":" + port);
            }
            logger.info("connect successfu...ftp服務器:" + hostname + ":" + port);
        } catch (MalformedURLException e) {
            logger.error(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return ftpClient;
    }


    /**
     * 上傳文件
     *
     * @param targetDir    ftp服務保存地址
     * @param fileName    上傳到ftp的文件名
     * @param inputStream 輸入文件流
     * @return
     */
    public boolean uploadFileToFtp(String targetDir, String fileName, InputStream inputStream) {
        boolean isSuccess = false;
        String servicePath = String.format("%s%s%s", basePath, "/", targetDir);
        FTPClient ftpClient = getFtpClient();
//      makeDirectory(ftpClient,servicePath); //創建文件夾
        
        
        
     // 切換到根目錄
        try {
			ftpClient.changeWorkingDirectory("/");
			String path = servicePath;
	        String[] pah = path.split("/");         
	        // 分層創建目錄
	        for (String pa : pah) {
	            System.out.println(pa);
	            ftpClient.makeDirectory(pa);
	            // 切到到對應目錄
	            ftpClient.changeWorkingDirectory(pa);
	        } 
		} catch (IOException e1) {
			e1.printStackTrace();
		}
        
        
        try {
            if (ftpClient.isConnected()) {
                logger.info("開始上傳文件到FTP,文件名稱:" + fileName);
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//設置上傳文件類型爲二進制,否則將無法打開文件
                ftpClient.makeDirectory(servicePath);
                ftpClient.changeWorkingDirectory(servicePath);
                //設置爲被動模式(如上傳文件夾成功,不能上傳文件,註釋這行,否則報錯refused:connect  )
                ftpClient.enterLocalPassiveMode();//設置被動模式,文件傳輸端口設置
                ftpClient.storeFile(fileName, inputStream);
                inputStream.close();
                ftpClient.logout();
                isSuccess = true;
                logger.info(fileName + "文件上傳到FTP成功");
            } else {
                logger.error("FTP連接建立失敗");
            }
        } catch (Exception e) {
            logger.error(fileName + "文件上傳到FTP出現異常");
            logger.error(e.getMessage(), e);
        } finally {
            closeFtpClient(ftpClient);
            closeStream(inputStream);
        }
        return isSuccess;
    }

    public void closeStream(Closeable closeable) {
        if (null != closeable) {
            try {
                closeable.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    //改變目錄路徑
    public boolean changeWorkingDirectory(FTPClient ftpClient, String directory) {
        boolean flag = true;
        try {
            flag = ftpClient.changeWorkingDirectory(directory);
            if (flag) {
                logger.info("進入文件夾" + directory + " 成功!");

            } else {
                logger.info("進入文件夾" + directory + " 失敗!開始創建文件夾");
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return flag;
    }

    //創建多層目錄文件,如果有ftp服務器已存在該文件,則不創建,如果無,則創建
    public boolean CreateDirecroty(FTPClient ftpClient, String remote) throws IOException {
        boolean success = true;

        String directory = remote;
        if (!remote.endsWith(File.separator)) {
            directory = directory + File.separator;
        }
        // 如果遠程目錄不存在,則遞歸創建遠程服務器目錄
        if (!directory.equalsIgnoreCase(File.separator) && !changeWorkingDirectory(ftpClient, new String(directory))) {
            int start = 0;
            int end = 0;
            if (directory.startsWith(File.separator)) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf(File.separator, start);
            String path = "";
            String paths = "";
            while (true) {
                String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
                path = path + File.separator + subDirectory;
                if (!existFile(ftpClient, path)) {
                    if (makeDirectory(ftpClient, subDirectory)) {
                        changeWorkingDirectory(ftpClient, subDirectory);
                    } else {
                        logger.error("創建目錄[" + subDirectory + "]失敗");
                        changeWorkingDirectory(ftpClient, subDirectory);
                    }
                } else {
                    changeWorkingDirectory(ftpClient, subDirectory);
                }

                paths = paths + File.separator + subDirectory;
                start = end + 1;
                end = directory.indexOf(File.separator, start);
                // 檢查所有目錄是否創建完畢
                if (end <= start) {
                    break;
                }
            }
        }
        return success;
    }

    //判斷ftp服務器文件是否存在
    public boolean existFile(FTPClient ftpClient, String path) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        if (ftpFileArr.length > 0) {
            flag = true;
        }
        return flag;
    }

    //創建目錄
    public boolean makeDirectory(FTPClient ftpClient, String dir) {
        boolean flag = true;
        try {
            flag = ftpClient.makeDirectory(dir);
            if (flag) {
                logger.info("創建文件夾" + dir + " 成功!");

            } else {
                logger.info("創建文件夾" + dir + " 失敗!");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return flag;
    }

    /**
     * 下載文件 *
     *
     * @param pathName FTP服務器文件目錄 *
     * @param pathName 下載文件的條件*
     * @return
     */
    public boolean downloadFile(FTPClient ftpClient, String pathName, String targetFileName, String localPath) {
        boolean flag = false;
        OutputStream os = null;
        try {
            System.out.println("開始下載文件");
            //切換FTP目錄
            ftpClient.changeWorkingDirectory(pathName);
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                String ftpFileName = file.getName();
                if (targetFileName.equalsIgnoreCase(ftpFileName.substring(0, ftpFileName.indexOf(".")))) {
                    File localFile = new File(localPath);
                    os = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(file.getName(), os);
                    os.close();
                }
            }
            ftpClient.logout();
            flag = true;
            logger.info("下載文件成功");
        } catch (Exception e) {
            logger.error("下載文件失敗");
            logger.error(e.getMessage(), e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return flag;
    }

    /*下載文件*/
    public InputStream download(String ftpFile, FTPClient ftpClient) throws IOException {
        String servicePath = String.format("%s%s%s", basePath, "/", ftpFile);
        logger.info("【從文件服務器獲取文件流】ftpFile : " + ftpFile);
        if (Utils.isEmpty(servicePath)) {
            throw new RuntimeException("【參數ftpFile爲空】");
        }
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        ftpClient.enterLocalPassiveMode();
        ftpFile = new String(servicePath.getBytes("utf-8"), "iso-8859-1");
        return ftpClient.retrieveFileStream(ftpFile);
    }

    /**
     * 刪除文件 *
     *
     * @param pathname FTP服務器保存目錄 *
     * @param filename 要刪除的文件名稱 *
     * @return
     */
    public boolean deleteFile(String pathname, String filename) {
        boolean flag = false;
        FTPClient ftpClient = getFtpClient();
        try {
            logger.info("開始刪除文件");
            if (ftpClient.isConnected()) {
                //切換FTP目錄
                ftpClient.changeWorkingDirectory(pathname);
                ftpClient.enterLocalPassiveMode();
                ftpClient.dele(filename);
                ftpClient.logout();
                flag = true;
                logger.info("刪除文件成功");
            } else {
                logger.info("刪除文件失敗");

            }
        } catch (Exception e) {
            logger.error("刪除文件失敗");
            logger.error(e.getMessage(), e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return flag;
    }

    public void closeFtpClient(FTPClient ftpClient) {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.disconnect();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    public InputStream downloadFile(String pathname, String filename) {
    	FTPClient ftpClient = getFtpClient();
    	String filePath = "company/3101051020110114/annexes_url";
        InputStream inputStream = null;
        try {
            System.out.println("開始下載文件");
            //切換FTP目錄
            ftpClient.changeWorkingDirectory(filePath);
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
            	System.err.println(file.getName()+"file.getName()");
                if (filename.equalsIgnoreCase(file.getName())) {
                	System.err.println("找到文件了");
                    inputStream = ftpClient.retrieveFileStream(file.getName());
                    break;
                }
            }
            ftpClient.logout();
            logger.info("下載文件成功");
        } catch (Exception e) {
            logger.error("下載文件失敗");
            logger.error(e.getMessage(), e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return inputStream;
    }
}


controller代碼如下:

@RequestMapping(value = "/C20000009",method = RequestMethod.POST)
    public Result addPhotoToFTP(MultipartFile file,HttpServletRequest request){
		String path = request.getParameter("path");
		//給圖片起一個新的名稱,防止在圖片名稱重複
        String msg = "";
        int code = 0;
        if(file!=null){
            try {
            	//圖片上傳,調用ftp工具類 image 上傳的文件夾名稱,newname 圖片名稱,inputStream
                boolean hopson = ftpUtil.uploadFileToFtp(path, file.getOriginalFilename(), file.getInputStream());
                if(hopson) {
                	// 把圖片信息存入到數據庫中
                	msg = "上傳成功";
                }
            } catch (Exception e) {
            	msg = "上傳失敗";
            	code = -1;
                e.printStackTrace();
            }
        }
		return Result.error(code, msg);
    }
	
	/**
	 * 功能代碼  C20000010
	 * 功能名稱 deletePhotoToFTP 
	 * 功能描述 刪除FTP上的文件
	 * @return
	 */
	@RequestMapping(value = "/C20000010",method = RequestMethod.POST)
    public Result deletePhotoToFTP(@RequestBody Map<String, String> params){
		String path =  params.get("path");
		String filename =  params.get("fileName");
        String msg = "";
        int code = 0;
	    try {
	    	boolean result = ftpUtil.deleteFile(path, filename);
	        if (result) {
	           	msg = "刪除成功";
	   		}else {
	   			msg = "刪除失敗";
	   	        code = -1;
	   		}
		} catch (Exception e) {
			msg = "刪除失敗";
		    code = -1;
		}
        
		return Result.error(code, msg);
    }

四:從ftp上下載文件到ftp

controller代碼:

@RequestMapping(value = "/C20000012",method = { RequestMethod.POST }, produces = "application/json; charset=utf-8")
    @ResponseBody
    public Result downloadFileByFTP(@RequestBody Map<String, Object> params,HttpServletRequest request,HttpServletResponse response)throws Exception {
		String filePath = params.get("filePath").toString();
		String fileName = params.get("fileName").toString();
		String msg = "";
        int code = 0;
         //當文件路徑爲空
         if (Utils.isEmpty(filePath)) {
             throw new IOException("File'" + filePath + "'is empty");
         } else {
        	// 1.讀取要下載的內容
        	 InputStream in = ftpUtil.downloadFile(filePath, fileName);
        	// 2. 告訴瀏覽器下載的方式以及一些設置
             // 解決文件名亂碼問題,獲取瀏覽器類型,轉換對應文件名編碼格式,IE要求文件名必須是utf-8, firefo要求是iso-8859-1編碼
             String agent = request.getHeader("user-agent");
             if (agent.contains("FireFox")) {
            	 fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
             } else {
            	 fileName = URLEncoder.encode(fileName, "UTF-8");
             }
             // 設置下載文件的mineType,告訴瀏覽器下載文件類型
             String mineType = request.getServletContext().getMimeType(fileName);
             response.setContentType(mineType);
             // 設置一個響應頭,無論是否被瀏覽器解析,都下載
             response.setHeader("Content-disposition", "attachment; filename=" + fileName);
             // 將要下載的文件內容通過輸出流寫到瀏覽器
        	 
        	 OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        		//創建存放文件內容的數組
        		byte[] buff =new byte[1024];
        		//所讀取的內容使用n來接收
        		int n;
        		//當沒有讀取完時,繼續讀取,循環
        		while((n=in.read(buff))!=-1){
        			//將字節數組的數據全部寫入到輸出流中
        			outputStream.write(buff,0,n);
        		}
        		//強制將緩存區的數據進行輸出
        		outputStream.flush();
        		//關流
        		outputStream.close();
        		in.close();
         }
         return Result.error(code, msg);
		
	}

前端js代碼:

 //下載企業附件
        previewfile(file){
        	var params = {
				     "filePath":file.url,
				     "fileName":file.name
			     }
			    return axios({
			          method: 'post',
			          url: baseURL+'api/C20000012',
			          data: params,
			          responseType:'blob'
			      }).then((response)=>{
			    	  console.log(response.data,"0000000000")
			    	  // 處理返回的文件流
			    	  const a = document.createElement('a');
		              const blob = new Blob([response.data]);
		              const blobUrl = window.URL.createObjectURL(blob);
		            	  download(blobUrl,file.name) ;
					}
					); 
        },
        download(blobUrl,fileName) {
          console.log(fileName,"3333333333333")
      	  const a = document.createElement('a');
      	  a.style.display = 'none';
      	  a.download = fileName;
      	  a.href = blobUrl;
      	  a.click();
      	},

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章