java使用Sftp上传文件(图片、视频等)到Linux服务器上

jar包依赖

<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
    <dependency>
      <groupId>com.jcraft</groupId>
      <artifactId>jsch</artifactId>
      <version>0.1.55</version>
    </dependency>
    
    <!-- Slf4j依赖 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>

上传下载工具类

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Vector;

/**
 * @Description 文件上传下载
 */
@Slf4j
public class UploadFileUtil {
    private static Session session;
    private static ChannelSftp channelSftp;
    /**
     * 获取sftp连接
     * @param ftpaddress 地址
     * @param ftpPassword 密码 
     * @param ftpUserName 用户名
     */
    public static ChannelSftp getSFTPClient(String ftpaddress, String ftpPassword,
                                            String ftpUserName,int ftpPort) {
        //开始时间  用于计时
        long startTime = System.currentTimeMillis();
        // 创建JSch对象
        JSch jsch = new JSch();
        Channel channel = null;
        try {
       		 //根据用户名,主机ip,端口获取一个Session对象
            session = jsch.getSession(ftpUserName, ftpaddress,ftpPort);
            // 设置密码
            session.setPassword(ftpPassword);
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            // 为Session对象设置properties
            session.setConfig(config);
            // 设置timeout时间
            //session.setTimeout(timeout);
            // 通过Session建立链接
            session.connect();
            // 打开SFTP通道
            channel = session.openChannel("sftp");
            // 建立SFTP通道的连接
            channel.connect();
            long endTime = System.currentTimeMillis();
            log.info("连接sftp成功耗时" + (endTime - startTime) + "毫秒");
            return (ChannelSftp) channel;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 判断目录是否存在
     * @param directory 
     * @param sftp
     * @return boolean
     */
    public static boolean isDirExist(String directory, ChannelSftp sftp) {
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            log.info("目录"+directory+"已存在");
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                log.info("目录"+directory+"不存在");
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;
    }

    /**
     * 创建目录
     * @param createpath
     * @param sftp
     */
    public static void createDir(String createpath, ChannelSftp sftp) {
        try {
            String pathArry[] = createpath.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(filePath.toString(),sftp)) {
                    sftp.cd(filePath.toString());
                } else {
                    // 建立目录
                    sftp.mkdir(filePath.toString());
                    log.info("创建目录"+filePath.toString()+"成功");
                    // 进入并设置为当前目录
                    sftp.cd(filePath.toString());
                    log.info("进入目录"+filePath.toString());
                }
            }
            sftp.cd(createpath);
        } catch (SftpException e) {
//            throw new SystemException("创建路径错误:" + createpath);
        }
    }

    /**
     * 关闭链接资源
     */
    public static void close() {
        if (channelSftp != null && channelSftp.isConnected()) {
            channelSftp.disconnect();
        }
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
       log.info("关闭连接资源");
    }

    /**
     * @Description //
     *      * @Param [host:上传主机IP, port:端口22, userName:登录名, password:密码
     *      *   remoteFile:上传路径,in:输入流格式文件, pathName:文件名称]
     * @param host 上传主机IP
     * @param port 端口 默认22
     * @param userName 登录名
     * @param password 密码
     * @param remoteFile 上传服务器路径
     * @param in 输入流格式文件
     * @param pathName 上传文件名称
     * @return boolean
     */
    public static boolean uploadFile(String host, int port, String userName, String password, String remoteFile, InputStream in, String pathName){
        try{
            //建立连接
            if (channelSftp == null || !channelSftp.isConnected()) {
                channelSftp=getSFTPClient(host,password,userName,port);
            }
            //判断文件夹是否存在,不存在则创建
            if (isDirExist(remoteFile,channelSftp)) {
                channelSftp.put(in, remoteFile + "/" +pathName);
                log.info("文件上传成功,文件路径"+remoteFile + "/" +pathName);
                close();
                return true;
            } else {
                //创建文件夹再上传文件
                createDir(remoteFile ,channelSftp);
                channelSftp.put(in, remoteFile + "/" +pathName);
                log.info("文件上传成功,文件路径"+remoteFile + "/" +pathName);
                close();
                return true;
            }
        }catch(Exception e){
            e.printStackTrace();
            close();
        }
        return false;

    }

    /**
     * 文件夹上传
     * @param host sftp地址
     * @param port sftp端口
     * @param userName 登录名
     * @param password 密码
     * @param file 上传的文件夹
     * @param remoteFile sftp服务器文件存放路径
     * @return true 成功,false 失败
     */
    public static boolean uploadDstFile(String host, int port, String userName, String password,
                                        MultipartFile[] file, String remoteFile){
        boolean b = false;
        //建立连接
        if (channelSftp == null || !channelSftp.isConnected()) {
            channelSftp=getSFTPClient(host,password,userName,port);
        }
        if (channelSftp.isConnected()) {
            b = uploadFiles(file,remoteFile);//循环迭代文件夹
            close();//关闭连接
        }
        return b;
    }


    /**
     * 循环读取文件夹里面的文件上传,不支持文件夹里面嵌套文件夹上传
     * @param file  文件
     * @param remoteFile 服务器路径
     * @return
     */
    private static  boolean uploadFiles(MultipartFile[] file, String remoteFile) {
        try {
            for (int i = 0; i < file.length; i++) {
                InputStream in = null;
                try {
                    in = file[i].getInputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (i == 0) {//获取设置文件夹名称
                    remoteFile = remoteFile + "/" + file[i].getOriginalFilename().substring(0, file[i].getOriginalFilename().lastIndexOf("/"));
                }
                //获取设置文件名称
                String originalFilename = file[i].getOriginalFilename().substring(file[i].getOriginalFilename().lastIndexOf("/"));
                //判断文件夹是否存在,存在则直接上传
                if (isDirExist(remoteFile, channelSftp)) {
                    channelSftp.put(in, remoteFile + "/" + originalFilename);
                    log.info("文件上传成功,文件路径" + remoteFile + "/" + originalFilename);
                } else {
                    //创建文件夹在上传文件
                    createDir(remoteFile, channelSftp);
                    channelSftp.put(in, remoteFile + "/" + originalFilename);
                    log.info("文件上传成功,文件路径" + remoteFile + "/" + originalFilename);
                }
            }
        } catch (SftpException e) {
            e.printStackTrace();
        }
        close();
        return true;
    }

    /**
     * @Description 下载服务器目录下的全部文件
     * @param host 上传主机IP
     * @param port 端口 默认22
     * @param userName 登录名
     * @param password 密码
     * @param src 服务器文件目录
     * @param localPath 本地存放地址
     * @return boolean
     */
    public static boolean downloadFiles(String host, int port, String userName, String password, String src, String localPath){
        try{
            //建立连接
            if (channelSftp == null || !channelSftp.isConnected()) {
                channelSftp=getSFTPClient(host,password,userName,port);
            }
            //获取文件目录下所有的文件
            Vector vector = channelSftp.ls(src);
            for (Object item : vector) {
                if (item instanceof com.jcraft.jsch.ChannelSftp.LsEntry) {
                    String fileName = ((com.jcraft.jsch.ChannelSftp.LsEntry) item).getFilename();
                    if (fileName.equals(".") || fileName.equals("..")) {
                        continue;
                    }
                    System.out.println(fileName);
                    File localpath = new File(localPath);
                    File[] fileList = localpath.listFiles();
                    if (!localpath.exists()) {
                        localpath.mkdirs();
                        localPath = localpath.getPath();
                    }
                    for (File file : fileList) {
                        if (fileName.equals(file.getName())) {
                            file.delete();
                        }
                    }
                    System.out.println(localPath);
                    String localFileName = localPath + File.separator + fileName;

                    channelSftp.get(src + "/" + fileName, localPath);
                    close();
                    return true;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
            close();
        }
        return false;

    }

    /**
     * @Description 下载目录下的指定文件
     * @param host 上传主机IP
     * @param port 端口 默认22
     * @param userName 登录名
     * @param password 密码
     * @param src 服务器文件目录
     * @param localPath 本地存放地址
     * @param fileName 指定文件名
     * @return boolean
     */
    public static boolean downloadFile(String host, int port, String userName, String password, String src, String localPath,String fileName){
        try{
            //建立连接
            if (channelSftp == null || !channelSftp.isConnected()) {
                channelSftp=getSFTPClient(host,password,userName,port);
            }
            System.out.println(src);
            // 下载文件的存放地址不存在则自动新建目录
            File localpath = new File(localPath);
            if (!localpath.exists()) {
                localpath.mkdirs();
                localPath = localpath.getPath();
            }
            channelSftp.get(src + "/" + fileName , localPath);
            close();
            return true;

        }catch(Exception e){
            e.printStackTrace();
            close();
        }
        return false;
    }
}

接口测试,使用postman测试

/**
   * 上传文件到服务器
   * @param request
   * @param file
   * @return
   * @throws IOException
   */
  @RequestMapping(value = "/upload",method = RequestMethod.POST)
  public String upload(HttpServletRequest request, MultipartFile file) throws IOException {
  	// 获取到上传文件的名字
    String fileName = file.getOriginalFilename();
    // 转换成输入流的方式
    InputStream inputStream = file.getInputStream();
    // 在这里可以修改的文件名称
    /*String imagesuffix = fileName.substring(fileName.lastIndexOf("."));//获取文件后缀
    String filename="上传"+imagesuffix;//拼接成你想要的名字*/
    // host sftp地址
    String host = "1.1.1.1";
    // port sftp端口
    int port = 22;
    // userName 登录名
    String userName = "root";
    // password 密码
    String password = "root";
    // remoteFile sftp服务器文件存放路径
    String remoteFile = "/home/atc/upload";
    boolean root = UploadFileUtil.uploadFile(host,port,userName,password,remoteFile,inputStream,fileName);
    return "1";
  }

  /**
   * 上传文件夹到服务器
   * @param request
   * @param file
   * @return
   * @throws IOException
   */
  @RequestMapping(value = "/uploadDir",method = RequestMethod.POST)
  public String uploadDir(HttpServletRequest request,MultipartFile[] file) throws IOException {
    if (file!=null) {
      // host sftp地址
      String host = "1.1.1.1";
      // port sftp端口
      int port = 22;
      // userName 登录名
      String userName = "root";
      // password 密码
      String password = "root";
      // remoteFile sftp服务器文件存放路径
      String remoteFile = "/home/atc/upload";
      boolean root = UploadFileUtil.uploadDstFile(host,port,userName,password,file,remoteFile);
    }
    return "";
  }

  /**
   * 下载服务器指定文件
   * @param src 文件所在位置+文件名
   * @param fileName 指定文件名
   * @return
   * @throws IOException
   */
  @RequestMapping(value = "/download",method = RequestMethod.POST)
  public String download(String src,String fileName) throws IOException {
    // host sftp地址
    String host = "1.1.1.1";
    // port sftp端口
    int port = 22;
    // userName 登录名
    String userName = "root";
    // password 密码
    String password = "root";
	//  String path = "/home/atc/upload/"+fileName;
    String localPath = "/Users/Desktop/download/";
    boolean result = UploadFileUtil.downloadFile(host,port,userName,password,src,localPath,fileName);
    return "1";
  }

视频上传需在配置文件中配置文件大小

# 视频上传配置文件大小,根据需求配置
spring.servlet.multipart.max-file-size = 9967920994
spring.servlet.multipart.max-request-size = 9967920994