Dubbo+SpringBoot项目使用FTP上传和下载文件

前言:公司新项目使用了dubbo微服务+springboot的架构,中间注册的时候需要把相关文件上传到FTP服务器中,并且在审核的时候可以下载。

一、准备工作

1.搭建ftp服务器

公司测试服务器是window系统的,搭建ftp可以参考这篇文章https://www.jianshu.com/p/ece21421e246。

2.相关类库引用

在需要使用的模块的pom文件中引用相关包


      commons-net
      commons-net
      3.6

3.创建文件上传与下载的工具类

package org.guoxn.base.api.util;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.List;

/**
 * @author Created by YangFan.
 * @date 2019/8/7
 * 功能: ftp工具类
 */
@Component
@ConfigurationProperties(prefix = "ftp")
public class FTPUtil {

    private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class);

    public FTPUtil() {

    }

    public FTPUtil(String ip, int port, String user, String pwd) {
        this.ip = ip;
        this.port = port;
        this.username = user;
        this.password = pwd;
    }

    public boolean uploadFile(List fileList, String fileDirectory) throws IOException {
        logger.info("开始连接ftp服务器");
        boolean result = uploadFile(fileDirectory, fileList);
        logger.info("开始连接ftp服务器,结束上传,上传结果:{}");
        return result;
    }

    /**
     * 上传文件
     *
     * @param pathname    ftp服务保存地址
     * @param fileName    上传到ftp的文件名
     * @param inputStream 输入文件流
     * @return
     */
    public boolean uploadFile(String pathname, String fileName, InputStream inputStream) {
        boolean flag = false;
        try {
            System.out.println("开始上传文件");
            if (connectServer(this.ip, this.port, this.username, this.password)) {
                ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
                CreateDirecroty(pathname);
                ftpClient.makeDirectory(pathname);
                ftpClient.changeWorkingDirectory(pathname);
                ftpClient.storeFile(fileName, inputStream);
                inputStream.close();
                ftpClient.logout();
                flag = true;
            }
            System.out.println("上传文件成功");
        } catch (Exception e) {
            System.out.println("上传文件失败");
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    //创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建
    public boolean CreateDirecroty(String remote) throws IOException {
        boolean success = true;
        String directory = remote + "/";
        // 如果远程目录不存在,则递归创建远程服务器目录
        if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) {
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf("/", start);
            String path = "";
            String paths = "";
            while (true) {
                String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), 
                        "iso-8859-1");
                path = path + "/" + subDirectory;
                if (!existFile(path)) {
                    if (makeDirectory(subDirectory)) {
                        changeWorkingDirectory(subDirectory);
                    } else {
                        System.out.println("创建目录[" + subDirectory + "]失败");
                        changeWorkingDirectory(subDirectory);
                    }
                } else {
                    changeWorkingDirectory(subDirectory);
                }

                paths = paths + "/" + subDirectory;
                start = end + 1;
                end = directory.indexOf("/", start);
                // 检查所有目录是否创建完毕
                if (end <= start) {
                    break;
                }
            }
        }
        return success;
    }

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

    //创建目录
    public boolean makeDirectory(String dir) {
        boolean flag = true;
        try {
            flag = ftpClient.makeDirectory(dir);
            if (flag) {
                System.out.println("创建文件夹" + dir + " 成功!");

            } else {
                System.out.println("创建文件夹" + dir + " 失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    //改变目录路径
    public boolean changeWorkingDirectory(String directory) {
        boolean flag = true;
        try {
            flag = ftpClient.changeWorkingDirectory(directory);
            if (flag) {
                System.out.println("进入文件夹" + directory + " 成功!");

            } else {
                System.out.println("进入文件夹" + directory + " 失败!开始创建文件夹");
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        return flag;
    }

    private boolean uploadFile(String remotePath, List fileList) throws IOException {
        boolean uploaded = true;
        FileInputStream fis = null;
        //连接FTP服务器
        if (connectServer(this.ip, this.port, this.username, this.password)) {
            try {
                ftpClient.changeWorkingDirectory(remotePath);
                ftpClient.setBufferSize(1024);
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.enterLocalPassiveMode();
                for (File fileItem : fileList) {
                    fis = new FileInputStream(fileItem);
                    ftpClient.enterLocalPassiveMode();
                    String remote = new String(fileItem.getName().getBytes("GBK"), "iso-8859-1");
                    ftpClient.storeFile(remote, fis);
                }

            } catch (IOException e) {
                logger.error("上传文件异常", e);
                uploaded = false;
                e.printStackTrace();
            } finally {
                fis.close();
                ftpClient.disconnect();
            }
        }
        return uploaded;
    }

    private InputStream downloadFile(String remotePath, String fileName) {
        InputStream result = null;
        if (connectServer(this.ip, this.port, this.username, this.password)) {
            try {
                int reply;
                reply = ftpClient.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftpClient.disconnect();
                    return null;
                }
                // 转移到FTP服务器目录
                ftpClient.enterLocalPassiveMode();
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.changeWorkingDirectory(remotePath);
                FTPFile[] fs = ftpClient.listFiles();
                // 下载文件是否存在
                boolean flag = false;
                for (FTPFile ff : fs) {
                    byte[] bytes = ff.getName().getBytes("iso-8859-1");
                    String name = new String(bytes, "GBK");
                    if (name.equals(fileName)) {
                        result = ftpClient.retrieveFileStream(ff.getName());
                        flag = true;
                    }
                }
                if (!flag) {
                    logger.info("文件: " + fileName + "不存在 !");
                } else {
                    logger.info("下载成功 !");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ftpClient.isConnected()) {
                    try {
                        ftpClient.disconnect();
                    } catch (IOException ioe) {
                    }
                }
            }
        }
        return result;
    }


    /**
     * 从FTP服务器下载文件
     *
     * @param remotePath FTP服务器上的相对路径
     * @param fileName   要下载的文件名
     * @return 结果
     */
    public InputStream downFile(String remotePath, String fileName) {
        InputStream result = downloadFile(remotePath, fileName);
        return result;
    }


    private boolean connectServer(String ip, int port, String user, String pwd) {

        boolean isSuccess = false;
        ftpClient = new FTPClient();
        try {
            ftpClient.connect(ip);
            isSuccess = ftpClient.login(user, pwd);
        } catch (IOException e) {
            logger.error("连接FTP服务器异常", e);
        }
        return isSuccess;
    }


    private String ip;
    private int port;
    private String username;
    private String password;
    private FTPClient ftpClient;

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public FTPClient getFtpClient() {
        return ftpClient;
    }

    public void setFtpClient(FTPClient ftpClient) {
        this.ftpClient = ftpClient;
    }
}

4.调用方法

for (MultipartFile file : files) {
       String fileName = file.getOriginalFilename();
        //扩展名
        String fileExtensionName = fileName.substring(fileName.lastIndexOf(".") + 1);
        String uploadFileName = System.currentTimeMillis() + fileExtensionName;
        File fileDir = new File(path);
        if (!fileDir.exists()) {
            fileDir.setWritable(true);
            boolean result = fileDir.mkdirs();
        }
       //上传文件到项目临时文件
       File targetFile = new File(path, uploadFileName);
       file.transferTo(targetFile);
       //文件已经上传成功
       FTPUtil util = new FTPUtil(ip, port, username, password);
       boolean success = util.uploadFile(Lists.newArrayList(targetFile), directory);
       if (success) {
          System.out.println("上传成功");     
       }
      //已经上传到ftp服务器上,删除临时文件
      targetFile.delete();
 }

这里是循环处理多个文件的方法。

5.注意事项

dubbo中不能够传递multipartFile类型的数据,所以,我这里处理上传和下载都是在控制器中执行的。查网上资料,有一种解决办法,让service实现hessian协议,这个协议是基于HTTP通讯协议,可以完成文件数据传输,但是我按照教程尝试使用的时候,并没有成功,暂时没有解决问题。

你可能感兴趣的:(Dubbo+SpringBoot项目使用FTP上传和下载文件)