美文网首页
Dubbo+SpringBoot项目使用FTP上传和下载文件

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

作者: crossyf | 来源:发表于2019-10-22 09:57 被阅读0次

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

    一、准备工作

    1.搭建ftp服务器

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

    2.相关类库引用

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

    <dependency>
          <groupId>commons-net</groupId>
          <artifactId>commons-net</artifactId>
          <version>3.6</version>
    </dependency>
    

    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<File> 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<File> 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上传和下载文件

          本文链接:https://www.haomeiwen.com/subject/iuyqyctx.html