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();
      	},

 

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