前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用JSch库进行SFTP连接

使用JSch库进行SFTP连接

作者头像
品茗IT
发布2023-10-22 15:17:38
6570
发布2023-10-22 15:17:38
举报
文章被收录于专栏:品茗IT品茗IT

使用JSch库进行SFTP连接

一、概述

JSch是一个Java库,用于实现SSH2协议。JSch可以用于连接SSH服务器并进行各种远程操作,如文件传输、端口转发、远程执行命令等。

JSch可在Linux、Unix、Windows和其他平台上运行,并且与各种Java环境兼容,包括J2SE、J2EE、Android等。

JSch提供了一组接口和类,以及许多示例代码,使得连接SSH服务器非常容易。它还支持密码和密钥交换认证,并提供了丰富的错误处理机制。使用JSch,开发人员可以轻松地在Java应用程序中实现SSH连接和远程操作。

JSch是一个开源库,由JCraft开发和维护。官方网站(http://www.jcraft.com/jsch/)

连接SFTP服务器并进行文件传输,可以使用JSch库来实现。

二、JSch的使用

2.1 用户名密码方式

下面是使用用户名密码方式连接的一个示例:

代码语言:javascript
复制
package cn.pomit.ftp;

import com.jcraft.jsch.*;

import java.util.Properties;

public class TestFtp {
    public static String userName = "app";
    public static String password = "app";
    public static String ip = "127.0.0.1";

    public static void main(String asdp[]){
        try {
            // 定义本地文件路径和远程文件路径
            String localFilePath = "/path/to/local/file.txt";
            String remoteFilePath = "/path/to/remote/file.txt";
            ChannelSftp sftpChannel = getUserPasswordChannel();
            // 将本地文件上传到SFTP服务器上
            sftpChannel.put(localFilePath, remoteFilePath);
            // 从SFTP服务器上下载文件到本地
            sftpChannel.get(remoteFilePath, localFilePath);
            // 关闭SFTP连接
            sftpChannel.disconnect();
        }catch (SftpException e) {
            e.printStackTrace();
        }
    }

    public static ChannelSftp getUserPasswordChannel(){
        try {
            JSch jsch = new JSch();
            Session sshSession = jsch.getSession(userName, ip, 22);
            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            // 设置第一次登录时自动接受SSH服务器的公钥
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp");
            channel.connect();
            return channel;
        } catch (JSchException e) {
            throw new RuntimeException("连接sfpt失败", e);
        }
    }
}

使用密码的方式,会因为密码变化无法使用,还可以使用公私钥方式进行链接。

2.2 密钥方式

如果要使用密钥方式进行SFTP连接,需要将RSA私钥添加到JSch中,而不是设置用户名和密码。下面是一个示例代码,演示如何使用JSch连接到SFTP服务器并使用RSA密钥进行认证:

代码语言:javascript
复制
package cn.pomit.ftp;

import com.jcraft.jsch.*;

import java.util.Properties;

public class TestFtp {
    public static String userName = "app";
    public static String ip = "127.0.0.1";
    public static String priKeyBasePath = "";

    public static void main(String asdp[]){
        try {
            // 定义本地文件路径和远程文件路径
            String localFilePath = "/local/file.txt";
            String remoteFilePath = "/remote/file.txt";
            ChannelSftp sftpChannel = getUserPriKeyChannel();
            // 将本地文件上传到SFTP服务器上
            sftpChannel.put(localFilePath, remoteFilePath);
            // 从SFTP服务器上下载文件到本地
            sftpChannel.get(remoteFilePath, localFilePath);
            // 关闭SFTP连接
            sftpChannel.disconnect();
        }catch (SftpException e) {
            e.printStackTrace();
        }
    }

    public static ChannelSftp getUserPriKeyChannel(String asd[]){
        try {
            JSch jsch = new JSch();
            jsch.addIdentity(priKeyBasePath);
            Session sshSession = jsch.getSession(userName, ip, 22);
            Properties sshConfig = new Properties();
            // 设置第一次登录时自动接受SSH服务器的公钥
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp");
            channel.connect();
            return channel;
        } catch (JSchException e) {
            throw new RuntimeException("连接sfpt失败", e);
        }
    }
}

三、使用方式升华

上面介绍了如何使用JSch库进行sftp的连接。但如果使用频繁,我们常常考虑使用连接池来管理连接。

apache提供了一个通用的连接池GenericObjectPool,可以进行连接管理。而构造GenericObjectPool需要一个PooledObjectFactory和一个GenericObjectPoolConfig(可以使用默认配置)。

所以,我们可以造一个Factory实现PooledObjectFactory:

3.1 Sftp工厂

SftpFactory:

代码语言:javascript
复制
package cn.pomit.ftp;

import lombok.Data;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

import java.util.Properties;

@Data
public class SftpFactory extends BasePooledObjectFactory<ChannelSftp> {

    private FtpConfig properties;

    public SftpFactory(FtpConfig properties) {
        this.properties = properties;
    }

    /**
     * 创建连接
     * @return ChannelSftp
     */
    @Override
    public ChannelSftp create() {
        return getUserPasswordChannel();
    }

    public ChannelSftp getUserPasswordChannel(){
        try {
            JSch jsch = new JSch();
            Session sshSession = jsch.getSession(properties.getUserName(), properties.getIp(), properties.getPort());
            sshSession.setPassword(properties.getPassword());
            Properties sshConfig = new Properties();
            // 设置第一次登录时自动接受SSH服务器的公钥
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp");
            channel.connect();
            return channel;
        } catch (JSchException e) {
            throw new RuntimeException("连接sfpt失败", e);
        }
    }

    public ChannelSftp getUserPriKeyChannel(){
        try {
            JSch jsch = new JSch();
            jsch.addIdentity(properties.getPriKeyBasePath());
            Session sshSession = jsch.getSession(properties.getUserName(), properties.getIp(), properties.getPort());
            Properties sshConfig = new Properties();
            // 设置第一次登录时自动接受SSH服务器的公钥
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp");
            channel.connect();
            return channel;
        } catch (JSchException e) {
            throw new RuntimeException("连接sfpt失败", e);
        }
    }

    @Override
    public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) {
        return new DefaultPooledObject<>(channelSftp);
    }

    // 销毁对象
    @Override
    public void destroyObject(PooledObject<ChannelSftp> p) {
        ChannelSftp channelSftp = p.getObject();
        channelSftp.disconnect();
    }

}

这里,SftpFactory继承了BasePooledObjectFactory,也就实现了PooledObjectFactory。提供了生成ChannelSftp的方式。

3.2 Ftp密钥及连接池

里面用到了一个FtpConfig,是配置密钥、连接池参数的,代码如下: FtpConfig:

代码语言:javascript
复制
package cn.pomit.ftp;

import lombok.Data;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

/**
 * @author yangshengwen
 * @description FtpConfig
 * @since 2021/6/3 15:14
 **/
@Data
public class FtpConfig {
    /**
     * ip地址
     */
    private String ip;
    /**
     * 端口号
     */
    private int port;
    /**
     * 账号
     */
    private String userName;
    /**
     * 密码
     */
    private String password;
    /**
     * 操作目录
     */
    private String path;
    /**
     * 操作目录下存放项目的目录
     */
    private String projectPath;
    /**
     * 数据探索功能存放Csv文件目录
     */
    private String projectPathCsv;
    /**
     * 操作目录下存放临时文件的目录
     */
    private String publicPath;
    /**
     * 操作目录下存放模型训练多版本程序目录
     */
    private String programsPath;
    /**
     * 操作目录下存放模型预测多版本程序目录
     */
    private String programsPrdPath;
    /**
     * 创建文件夹
     */
    private String createDirectory;

    /**
     * 私钥文件地址
     */
    private String priKeyBasePath;

    private Pool pool;

    @Data
    public static class Pool extends GenericObjectPoolConfig {
        /**
         * 对象最大数量
         */
        private int maxTotal ;
        /**
         * 最大空闲对象数量
         */
        private int maxIdle ;
        /**
         * 最小空闲对象数量
         */
        private int minIdle ;

        /**
         * 当池耗尽时,阻塞的最长时间,为负值时无限等待
         */
        private long maxWaitMillis;

        /**
         * 从池中取出对象是是否检测可用
         */
        private boolean testOnBorrow;

        /**
         * 将对象返还给池时检测是否可用
         */
        private boolean testOnReturn;

        /**
         * 检查连接池对象是否可用
         */
        private boolean testWhileIdle;


    }
}
3.3 Sftp连接池使用
代码语言:javascript
复制
    FtpConfig config = new FtpConfig();
    //这里config需要set一些参数。
    
    SftpFactory sftpFactory = new SftpFactory(config);
    GenericObjectPool<ChannelSftp> pool = new GenericObjectPool<>(sftpFactory, sftpFactory.getProperties().getPool());
    ChannelSftp channelSftp = pool.borrowObject();
    // 将本地文件上传到SFTP服务器上
    sftpChannel.put(localFilePath, remoteFilePath);
    // 从SFTP服务器上下载文件到本地
    sftpChannel.get(remoteFilePath, localFilePath);
    // 归还SFTP连接
    pool.returnObject(channelSftp);
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用JSch库进行SFTP连接
  • 一、概述
  • 二、JSch的使用
    • 2.1 用户名密码方式
      • 2.2 密钥方式
      • 三、使用方式升华
        • 3.1 Sftp工厂
          • 3.2 Ftp密钥及连接池
            • 3.3 Sftp连接池使用
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档