• springboot SFTP 文件上传下载功能


    新增sftp.properies

    文件保存 sftp服务器信息

    # 协议
    sftp.client.protocol=sftp
    # ip地址
    sftp.client.host=改成自己的文件服务器地址
    # 端口
    sftp.client.port=22
    # 用户名
    sftp.client.username=root
    # 密码
    sftp.client.password=改成自己的密码
    # 文件上传根路径
    sftp.client.root=/home/sftp/
    # 密钥文件路径
    sftp.client.privateKey=
    # 密钥的密码
    sftp.client.passphrase=
    #
    sftp.client.sessionStrictHostKeyChecking=no
    # session连接超时时间
    sftp.client.sessionConnectTimeout=15000
    # channel连接超时时间
    sftp.client.channelConnectedTimeout=15000

    SftpProperties.java 文件

    package cn.rc.properties;
    
    import lombok.Data;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    @Data
    @Component
    public class SftpProperties {
        @Value("${sftp.client.host}")
        private String host;
    
        @Value("${sftp.client.port}")
        private Integer port;
    
        @Value("${sftp.client.protocol}")
        private String protocol;
    
        @Value("${sftp.client.username}")
        private String username;
    
        @Value("${sftp.client.password}")
        private String password;
    
        @Value("${sftp.client.root}")
        private String root;
    
        @Value("${sftp.client.privateKey}")
        private String privateKey;
    
        @Value("${sftp.client.passphrase}")
        private String passphrase;
    
        @Value("${sftp.client.sessionStrictHostKeyChecking}")
        private String sessionStrictHostKeyChecking;
    
        @Value("${sftp.client.sessionConnectTimeout}")
        private Integer sessionConnectTimeout;
    
        @Value("${sftp.client.channelConnectedTimeout}")
        private Integer channelConnectedTimeout;
    
    }

    Application.java   文件启动类

    引入属性加上文件上传大小的设置

    /**
     * Eureka服务端
     *
     * @author wanjun
     */
    @SpringBootApplication
    @EnableDiscoveryClient
    @Slf4j
    @MapperScan(basePackages = {"cn.rc.mapper"})
    @PropertySource({"sftp.properties"})
    public class Application {
    
        public static void main(String[] args) throws Exception {
            SpringApplication.run(Application.class, args);
        }
    
        /**
         * 文件上传配置
         * @return
         */
        @Bean
        public MultipartConfigElement multipartConfigElement() {
            MultipartConfigFactory factory = new MultipartConfigFactory();
            //文件最大
            //factory.setMaxFileSize("1024KB"); //KB,MB
            /// 设置总上传数据总大小
            factory.setMaxRequestSize("20480KB"); //最大上传为4M
            return factory.createMultipartConfig();
        }
    }
    
    

    文件上传下载的接口

    FileSystemController.java

    package cn.rc.controller;
    
    import cn.rc.properties.SftpProperties;
    import cn.rc.service.FileSystemService;
    import com.oracle.tools.packager.Log;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.List;
    
    @Controller
    public class FileSystemController {
        @Autowired
        private FileSystemService fileSystemService;
    
        /**
         * 实现多文件上传
         */
        @RequestMapping(value = "upload", method = RequestMethod.POST)
        @ResponseBody
        public Boolean upload(@RequestParam("files") List<MultipartFile> files, HttpServletRequest request) {
            if (files.isEmpty()) {
                return false;
            }
            for (MultipartFile file : files) {
                String fileName = file.getOriginalFilename();
                int size = (int) file.getSize();
                System.out.println(fileName + "-->" + size);
                if (file.isEmpty()) {
                    return false;
                } else {
                    try {
                        File dest = multipartFileToFile(file);
                        fileSystemService.uploadFile("/513_education/" + fileName, dest);
                    } catch (Exception e) {
                        e.printStackTrace();
                        return false;
                    }
                }
            }
            return true;
        }
    
    
        @RequestMapping("/download")
        public String downLoad(HttpServletResponse response) throws Exception {
            String downUrl = "/home/sftp/513_education/" + "20200225223754.csv";
            File file = fileSystemService.downloadFile(downUrl);
            String filename = file.getName();
            if (file.exists()) { //判断文件父目录是否存在
                response.setContentType("application/vnd.ms-excel;charset=UTF-8");
                response.setCharacterEncoding("UTF-8");
                // response.setContentType("application/force-download");
                response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(filename, "UTF-8"));
                byte[] buffer = new byte[1024];
                FileInputStream fis = null; //文件输入流
                BufferedInputStream bis = null;
    
                OutputStream os = null; //输出流
                try {
                    os = response.getOutputStream();
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer);
                        i = bis.read(buffer);
                    }
    
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("----------file download---" + filename);
                try {
                    bis.close();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
    
        public static File multipartFileToFile(MultipartFile multiFile) {
            // 获取文件名
            String fileName = multiFile.getOriginalFilename();
            // 获取文件后缀
            String prefix = fileName.substring(fileName.lastIndexOf("."));
            // 若需要防止生成的临时文件重复,可以在文件名后添加随机码
    
            try {
                File file = File.createTempFile(fileName, prefix);
                multiFile.transferTo(file);
                return file;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    FileSystemService
    package cn.rc.service;
    
    import java.io.File;
    import java.io.InputStream;
    
    public interface FileSystemService {
    
        boolean uploadFile(String targetPath, InputStream inputStream) throws Exception;
    
        boolean uploadFile(String targetPath, File file) throws Exception;
    
        File downloadFile(String targetPath) throws Exception;
    
        boolean deleteFile(String targetPath) throws Exception;
    }


    FileSystemServiceImpl.java
    package cn.rc.service.impl;
    
    import cn.rc.properties.SftpProperties;
    import cn.rc.service.FileSystemService;
    import com.jcraft.jsch.*;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.io.*;
    import java.util.Arrays;
    
    @Slf4j
    @Service("fileSystemService")
    public class FileSystemServiceImpl implements FileSystemService {
    
        @Autowired
        private SftpProperties config;
    
        // 设置第一次登陆的时候提示,可选值:(ask | yes | no)
        private static final String SESSION_CONFIG_STRICT_HOST_KEY_CHECKING = "StrictHostKeyChecking";
    
        /**
         * 创建SFTP连接
         *
         * @return
         * @throws Exception
         */
        private ChannelSftp createSftp() throws Exception {
            JSch jsch = new JSch();
            log.info("Try to connect sftp[" + config.getUsername() + "@" + config.getHost() + "], use password[" + config.getPassword() + "]");
    
            Session session = createSession(jsch, config.getHost(), config.getUsername(), config.getPort());
            session.setPassword(config.getPassword());
            session.connect(config.getSessionConnectTimeout());
    
            log.info("Session connected to {}.", config.getHost());
    
            Channel channel = session.openChannel(config.getProtocol());
            channel.connect(config.getChannelConnectedTimeout());
    
            log.info("Channel created to {}.", config.getHost());
    
            return (ChannelSftp) channel;
        }
    
        /**
         * 加密秘钥方式登陆
         *
         * @return
         */
        private ChannelSftp connectByKey() throws Exception {
            JSch jsch = new JSch();
    
            // 设置密钥和密码 ,支持密钥的方式登陆
            if (StringUtils.isNotBlank(config.getPrivateKey())) {
                if (StringUtils.isNotBlank(config.getPassphrase())) {
                    // 设置带口令的密钥
                    jsch.addIdentity(config.getPrivateKey(), config.getPassphrase());
                } else {
                    // 设置不带口令的密钥
                    jsch.addIdentity(config.getPrivateKey());
                }
            }
            log.info("Try to connect sftp[" + config.getUsername() + "@" + config.getHost() + "], use private key[" + config.getPrivateKey()
                    + "] with passphrase[" + config.getPassphrase() + "]");
    
            Session session = createSession(jsch, config.getHost(), config.getUsername(), config.getPort());
            // 设置登陆超时时间
            session.connect(config.getSessionConnectTimeout());
            log.info("Session connected to " + config.getHost() + ".");
    
            // 创建sftp通信通道
            Channel channel = session.openChannel(config.getProtocol());
            channel.connect(config.getChannelConnectedTimeout());
            log.info("Channel created to " + config.getHost() + ".");
            return (ChannelSftp) channel;
        }
    
        /**
         * 创建session
         *
         * @param jsch
         * @param host
         * @param username
         * @param port
         * @return
         * @throws Exception
         */
        private Session createSession(JSch jsch, String host, String username, Integer port) throws Exception {
            Session session = null;
    
            if (port <= 0) {
                session = jsch.getSession(username, host);
            } else {
                session = jsch.getSession(username, host, port);
            }
    
            if (session == null) {
                throw new Exception(host + " session is null");
            }
    
            session.setConfig(SESSION_CONFIG_STRICT_HOST_KEY_CHECKING, config.getSessionStrictHostKeyChecking());
            return session;
        }
    
        /**
         * 关闭连接
         *
         * @param sftp
         */
        private void disconnect(ChannelSftp sftp) {
            try {
                if (sftp != null) {
                    if (sftp.isConnected()) {
                        sftp.disconnect();
                    } else if (sftp.isClosed()) {
                        log.info("sftp is closed already");
                    }
                    if (null != sftp.getSession()) {
                        sftp.getSession().disconnect();
                    }
                }
            } catch (JSchException e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 将inputStream上传到指定路径下(单级或多级目录)
         *
         * @param targetPath  路径+文件名  比如/ home/513_education/test.xlsl
         * @param inputStream
         * @return
         * @throws Exception
         */
        @Override
        public boolean uploadFile(String targetPath, InputStream inputStream) throws Exception {
            ChannelSftp sftp = this.createSftp();
            try {
                sftp.cd(config.getRoot());
                log.info("Change path to {}", config.getRoot());
    
                int index = targetPath.lastIndexOf("/");
                String fileDir = targetPath.substring(0, index);
                String fileName = targetPath.substring(index + 1);
                boolean dirs = this.createDirs(fileDir, sftp);
                if (!dirs) {
                    log.error("Remote path error. path:{}", targetPath);
                    throw new Exception("Upload File failure");
                }
                sftp.put(inputStream, fileName);
                return true;
            } catch (Exception e) {
                log.error("Upload file failure. TargetPath: {}", targetPath, e);
                throw new Exception("Upload File failure");
            } finally {
                this.disconnect(sftp);
            }
        }
    
    
        /**
         * 创建多级目录
         *
         * @param dirPath
         * @param sftp
         * @return
         */
        private boolean createDirs(String dirPath, ChannelSftp sftp) {
            if (dirPath != null && !dirPath.isEmpty()
                    && sftp != null) {
                String[] dirs = Arrays.stream(dirPath.split("/"))
                        .filter(StringUtils::isNotBlank)
                        .toArray(String[]::new);
    
                for (String dir : dirs) {
                    try {
                        sftp.cd(dir);
                        log.info("Change directory {}", dir);
                    } catch (Exception e) {
                        try {
                            sftp.mkdir(dir);
                            log.info("Create directory {}", dir);
                        } catch (SftpException e1) {
                            log.error("Create directory failure, directory:{}", dir, e1);
                            e1.printStackTrace();
                        }
                        try {
                            sftp.cd(dir);
                            log.info("Change directory {}", dir);
                        } catch (SftpException e1) {
                            log.error("Change directory failure, directory:{}", dir, e1);
                            e1.printStackTrace();
                        }
                    }
                }
                return true;
            }
            return false;
        }
    
    
        /**
         * 将文件上传到指定目录
         *
         * @param targetPath
         * @param file
         * @return
         * @throws Exception
         */
        @Override
        public boolean uploadFile(String targetPath, File file) throws Exception {
            return this.uploadFile(targetPath, new FileInputStream(file));
        }
    
        /**
         * 下载文件
         *
         * @param targetPath
         * @return
         * @throws Exception
         */
        @Override
        public File downloadFile(String targetPath) throws Exception {
            ChannelSftp sftp = this.createSftp();
            OutputStream outputStream = null;
            try {
                sftp.cd(config.getRoot());
                log.info("Change path to {}", config.getRoot());
    
                File file = new File(targetPath.substring(targetPath.lastIndexOf("/") + 1));
    
                outputStream = new FileOutputStream(file);
                sftp.get(targetPath, outputStream);
                log.info("Download file success. TargetPath: {}", targetPath);
                return file;
            } catch (Exception e) {
                log.error("Download file failure. TargetPath: {}", targetPath, e);
                throw new Exception("Download File failure");
            } finally {
                if (outputStream != null) {
                    outputStream.close();
                }
                this.disconnect(sftp);
            }
        }
    
        /**
         * 删除文件
         *
         * @param targetPath
         * @return
         * @throws Exception
         */
        @Override
        public boolean deleteFile(String targetPath) throws Exception {
            ChannelSftp sftp = null;
            try {
                sftp = this.createSftp();
                sftp.cd(config.getRoot());
                sftp.rm(targetPath);
                return true;
            } catch (Exception e) {
                log.error("Delete file failure. TargetPath: {}", targetPath, e);
                throw new Exception("Delete File failure");
            } finally {
                this.disconnect(sftp);
            }
        }
    }

    启动项目并用postman测试

    选择文件后请求,响应true

    查看控制台打印输出:

    登陆文件服务器 查看相应目录下:

    文件已经被上传

  • 相关阅读:
    排序算法(一)冒泡法
    java是传值还是传引用
    赫夫曼树与赫夫曼编码
    数据结构的相关概念
    字符集和字符编码的区别
    redis为什么选择单线程工作模型
    GET和POST请求的核心区别
    MySQL数据类型及后面小括号的意义
    java中的数据类型
    Jedis无法连接centOS7上的redis
  • 原文地址:https://www.cnblogs.com/wanjun-top/p/12967795.html
Copyright © 2020-2023  润新知