✅ 推荐:使用 sshj(客户端连接 SSH)https://blog.csdn.net/z1353095373/article/details/149959817
适合:远程登录服务器、执行命令、上传/下载文件等。

❌ 不推荐:使用 jsch(客户端连接 SSH)
不支持 ssh 新版本算法。

package com.example.job.ssh.sftp.ga;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Properties;

/**
 * JSch - Java实现的SFTP(文件上传下载) - lihewei - 博客园
 * https://www.cnblogs.com/lihw/p/17168705.html#%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD-get--%E6%96%B9%E6%B3%95
 */
@Slf4j
public class SFTPChannel {
    private Session session = null;
    private Channel channel = null;
    private static final int TIMEOUT = 60000;

    /**
     * 登录sftp
     */
    public ChannelSftp getChannel(Map<String, String> sftpDetails) throws JSchException {
        String ftpHost = sftpDetails.get(SFTPConstants.SFTP_REQ_HOST);
        int ftpPort = Integer.parseInt(sftpDetails.get(SFTPConstants.SFTP_DEFAULT_PORT));
        String ftpUserName = sftpDetails.get(SFTPConstants.SFTP_REQ_USERNAME);
        String ftpPassword = sftpDetails.get(SFTPConstants.SFTP_REQ_PASSWORD);

        // 创建JSch对象
        JSch jsch = new JSch();
        // 根据用户名,主机ip,端口获取一个Session对象
        session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
        log.info("Session created.");
        if (ftpPassword != null) {
            session.setPassword(ftpPassword);
        }
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config); // 为Session对象设置properties
        session.setTimeout(TIMEOUT); // 设置timeout时间
        session.connect(); // 通过Session建立链接
        log.info("Session connected.");
        log.info("Opening Channel.");
        channel = session.openChannel("sftp"); // 打开SFTP通道
        channel.connect(); // 建立SFTP通道的连接
        log.info("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName
                + ", returning: " + channel);
        return (ChannelSftp) channel;
    }

    /**
     * 退出sftp
     */
    public void closeChannel() {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
    }

}

package com.example.job.ssh.sftp.ga;

public class SFTPConstants {
    public static final String SFTP_REQ_HOST = "xx.xx.xx.xxx";
    public static final String SFTP_DEFAULT_PORT = "22";
    public static final String SFTP_REQ_USERNAME = "root";
    public static final String SFTP_REQ_PASSWORD = "xxx";
}

package com.example.job.ssh.sftp.ga;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jcraft.jsch.ChannelSftp;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class SFTPGetTest {
    /**
     * 服务器上传名和原名 对应关系
     */
    private final static JSONObject FILE_REAL_NAME = JSONUtil.readJSONObject(FileUtil.file("sftp/ga/filenamemap.json"), CharsetUtil.CHARSET_UTF_8);
    /**
     * 服务器文件上传路径
     */
    private final static String STORAGE_FILE_PATH = "/home/docker-compose/ga-api/data/attachment/6514/yuqingmanage/submit/";

    public static void main(String[] args) throws Exception {
        // 新建临时路径
        String bashPath = "D:/data/ga/" + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_MS_PATTERN);
        String dstPath = bashPath + "/files/";
        String dstZipPath = bashPath + "/zip/ga_file.zip";
        FileUtil.mkdir(dstPath);

        // 设置主机ip,端口,用户名,密码
        Map<String, String> sftpDetails = new HashMap<>();
        sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, SFTPConstants.SFTP_REQ_HOST);
        sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, SFTPConstants.SFTP_REQ_USERNAME);
        sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, SFTPConstants.SFTP_REQ_PASSWORD);
        sftpDetails.put(SFTPConstants.SFTP_DEFAULT_PORT, SFTPConstants.SFTP_DEFAULT_PORT);

        // SFTP
        SFTPChannel channel = new SFTPChannel();
        ChannelSftp chSftp = channel.getChannel(sftpDetails);

        String src = null;
        try {
            int i = 1;
            for (Map.Entry<String, Object> map : FILE_REAL_NAME) {
                String storageFileName = map.getKey();
                String originalFileName = (String) map.getValue();
                // 服务器路径
                src = STORAGE_FILE_PATH + storageFileName;
                // 处理下载文件名为原名,重命名:增加序号,解决文件名重复问题
                String oriFileMainName = FileUtil.mainName(originalFileName);
                String oriFileExtName = FileUtil.extName(originalFileName);
                String oriFileNewName = i + "-" + oriFileMainName + "." + oriFileExtName;
                log.info("文件服务器存储名:{},对应原名:{}", storageFileName, oriFileNewName);

                // 下载路径
                String dst = dstPath + oriFileNewName;
                // 下载文件
                chSftp.get(src, dst);
                log.info("文件:{},下载完成", src);

                i++;
            }
        } catch (Exception e) {
            log.error("文件下载异常:" + src, e);
        } finally {
            chSftp.quit();
            channel.closeChannel();
        }

        // 压缩
        ZipUtil.zip(dstPath, dstZipPath);
        log.info("文件压缩完成:{}", dstZipPath);
    }

}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐