`
Psunmingjie
  • 浏览: 1155 次
  • 性别: Icon_minigender_1
  • 来自: 济南
文章分类
社区版块
存档分类
最新评论

SFTP使用JSCH库链接不断开解决方法

阅读更多
在处理银行业务的时候,数据交互还使用老旧的sftp技术,最近在使用sftp的JSCH库时发现,采用公私钥方式连接server,总是无法断开连接,研究发现这种模式下如果存在并发的链接时,disconnect方法实际不起左右,这样会产生大量链接,最终造成无法再链接上;解决办法采用Threadlocal镜像复制方式,为每个链接建立单独的工具对象


public class SftpUtil {
    private final static Logger          log       = LoggerFactory.getLogger(SftpUtil.class);

    /** SFTP */
    public static final String           SFTP      = "sftp";
    /** 通道 */
    private ChannelSftp                  channel;
    /** session */
    private Session                      session;

    /** 规避多线程并发不断开问题 */
    private static ThreadLocal<SftpUtil> sftpLocal = new ThreadLocal<SftpUtil>();

    /**
     * 获取sftpchannel
     * 
     * @param connectConfig 连接配置
     * @return
     * @throws Exception 
     * @throws JSchException
     */
    private void init(ConnectConfig connectConfig) throws Exception {
        String host = connectConfig.getHost();
        int port = connectConfig.getPort();

        String userName = connectConfig.getUserName();

        //创建JSch对象
        JSch jsch = new JSch();

        //添加私钥(信任登录方式)
        if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {
            jsch.addIdentity(connectConfig.getPrivateKey());
        }

        session = jsch.getSession(userName, host, port);
        if (log.isInfoEnabled()) {
            log.info(" JSCH Session created,sftpHost = {}, sftpUserName={}", host, userName);
        }

        //设置密码
        if (StringUtils.isNotBlank(connectConfig.getPassWord())) {
            session.setPassword(connectConfig.getPassWord());
        }

        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        //设置超时
        session.setTimeout(connectConfig.getTimeout());
        //建立连接
        session.connect();
        if (log.isInfoEnabled()) {
            log.info("JSCH Session connected.sftpHost = {}, sftpUserName={}", host, userName);
        }

        //打开SFTP通道
        channel = (ChannelSftp) session.openChannel(SFTP);
        //建立SFTP通道的连接
        channel.connect();
        if (log.isInfoEnabled()) {
            log.info("Connected successfully to sftpHost = {}, sftpUserName={}", host, userName);
        }
    }

    /**
     * 是否已连接
     * 
     * @return
     */
    private boolean isConnected() {
        return null != channel && channel.isConnected();
    }

    /**
     * 获取本地线程存储的sftp客户端
     * 
     * @return
     * @throws Exception 
     */
    public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {
        SftpUtil sftpUtil = sftpLocal.get();
        if (null == sftpUtil || !sftpUtil.isConnected()) {
            sftpLocal.set(new SftpUtil(connectConfig));
        }
        return sftpLocal.get();
    }

    /**
     * 释放本地线程存储的sftp客户端
     */
    public static void release() {
        if (null != sftpLocal.get()) {
            sftpLocal.get().closeChannel();
            sftpLocal.set(null);
        }
    }

    /**
     * 构造函数
     * <p>
     * 非线程安全,故权限为私有
     * </p>
     * 
     * @throws Exception 
     */
    private SftpUtil(ConnectConfig connectConfig) throws Exception {
        super();
        init(connectConfig);
    }

    /**
     * 关闭通道
     * 
     * @throws Exception
     */
    public void closeChannel() {
        if (null != channel) {
            try {
                channel.disconnect();
            } catch (Exception e) {
                log.error("关闭SFTP通道发生异常:", e);
            }
        }
        if (null != session) {
            try {
                session.disconnect();
            } catch (Exception e) {
                log.error("SFTP关闭 session异常:", e);
            }
        }
    }

    /**
     * 下载文件
     * 
     * @param downDir 下载目录
     * @param src 源文件
     * @param dst 保存后的文件名称或目录
     * @throws Exception
     */
    public void downFile(String downDir, String src, String dst) throws Exception {
        channel.cd(downDir);
        channel.get(src, dst);
    }

    /**
     * 删除文件
     * 
     * @param filePath 文件全路径
     * @throws SftpException
     */
    public void deleteFile(String filePath) throws SftpException {
        channel.rm(filePath);
    }

    @SuppressWarnings("unchecked")
    public List<String> listFiles(String dir) throws SftpException {
        Vector<LsEntry> files = channel.ls(dir);
        if (null != files) {
            List<String> fileNames = new ArrayList<String>();
            Iterator<LsEntry> iter = files.iterator();
            while (iter.hasNext()) {
                String fileName = iter.next().getFilename();
                if (StringUtils.equals(".", fileName) || StringUtils.equals("..", fileName)) {
                    continue;
                }
                fileNames.add(fileName);
            }
            return fileNames;
        }
        return null;
    }
}

 

分享到:
评论

相关推荐

    JSCH免费下载啦

    使用JSCH库进行SFTP文件传输的基本步骤如下: 1. 创建`Session`对象,设置主机、端口、用户名和密码。 2. 调用`Session.connect()`方法建立连接。 3. 创建`ChannelSftp`对象,通过`Session.openChannel("sftp")`...

    java版SFTP实现示例(使用jsch)

    在Java中,我们通常会使用第三方库如JSch来实现SFTP功能。 JSch(Java Secure Channel)是一个开源Java库,它允许开发者执行SSH2协议,包括SFTP。通过JSch,我们可以实现连接到远程服务器,创建、上传、下载、删除...

    jsch的jar包

    **JSCH库详解** JSCH(Java Secure Channel)是一个开源的Java库,它实现了SSH2协议,...尽管SFTP功能可能不是每个项目中的必需品,但了解和掌握JSCH的使用对于提升开发者的技能和解决问题的范围都是非常有价值的。

    SFTP资料及JAR包

    JSCH库的版本为0.1.8.jar,包含了所有必要的类和方法来处理SFTP操作。 在使用JSCH进行SFTP操作时,首先需要配置一个`JSch`实例,然后建立到远程服务器的会话。这通常涉及到设置主机名、端口号、用户名和密码(或...

    FTP文件上传下载删除+jsch.jar

    总之,通过JSCH库,你可以实现安全、可靠的FTP文件操作,即使在不支持FTP的环境中,也能利用SSH协议进行文件传输。这个库为Java开发者提供了一个强大且灵活的工具,用于在各种项目中实现远程文件管理。

    sftp上传下载 java

    首先,为了在Java中使用SFTP,我们需要一个支持SFTP的库,例如JSch(Java Secure Channel)。JSch是一个开源的Java库,提供了SSH2协议的实现,包括SFTP服务。在描述中提到的“jar包”可能就是JSch的库文件。要使用...

    JSCH0.1.46

    JSCH(Java Simple Connection Handler)是一个Java库,用于在客户端应用程序和远程服务器之间建立SSH(Secure Shell)连接。版本0.1.46是JSCH的最新版,它提供了丰富的功能,使开发者能够通过SSH协议在Java应用中...

    java sftp文件上传

    Java本身并不内置SFTP功能,但我们可以使用第三方库,如JSch(Java Secure Channel)或Apache Commons Net。JSch是常用的库,它实现了SSH2协议,包括SFTP子协议。 1. **安装JSch库** 在你的项目中添加JSch库。如果...

    JavaSFTP上传文件

    在Java编程中,SFTP(Secure File ...综上所述,Java操作SFTP上传和下载文件主要涉及到JSch库的使用,包括连接配置、通道创建、文件操作以及断开连接等步骤。在实际开发中,应结合具体需求,优化代码并确保安全性。

    jsch 1.49 官方包

    这个例子展示了如何使用JSch库创建SFTP会话并上传本地文件到远程服务器。 ### 注意事项 1. **安全风险**: 忽略主机key检查(`StrictHostKeyChecking=no`)是为了简化示例,但在生产环境中应谨慎处理,避免中间人攻击...

    sftp的工具类和jar包

    总的来说,理解并掌握如何使用`sftp的工具类和jar包`,如JSch库和自定义的`SFTPUtil`,对于进行Java中的SFTP编程至关重要。这些工具使我们能够在保证数据安全的前提下,便捷地进行跨网络的文件传输,广泛应用于自动...

    基于Java的实例源码-用Java写的SFTP代码.zip

    在Java中实现SFTP功能,通常会使用JSch库,这是一个Java实现的SSH2库,提供了解析、建立和维护SSH2连接的能力,包括SFTP子系统。 以下是一些关键的Java SFTP知识点: 1. **JSch库**:JSch是Java中实现SFTP的主要库...

    连接sftp服务器

    在IT行业中,SFTP...总的来说,Java中的SFTP操作涉及的主要知识点包括:JSch库的使用、SFTP协议、SSH连接、文件传输以及安全实践。通过这些知识,开发者可以构建安全可靠的文件传输功能,满足不同应用场景的需求。

    sftp-demo.rar

    总的来说,Java中的SFTP功能主要依赖于JSch库,通过创建Session和ChannelSftp对象,可以实现与SFTP服务器的连接、文件上传和断开连接等一系列操作。"sftp-demo"项目就是一个演示如何使用这些功能的实例。

    java 开发sftp下载上传

    首先,为了在Java中实现SFTP,我们需要一个支持SFTP的库,例如JSch(Java Secure Channel)。JSch是一个开源的Java库,它实现了SSH2协议,包括SFTP子协议。安装JSch库后,我们可以在项目中引入对应的jar包。 下面...

    jsch的jar包,包含0.1.51,0.1.52,0.1.53,0.1.54等这几个版本

    JSch,全称为Java Secure Channel,是一个开源的Java库,用于实现SSH(Secure Shell)协议。这个库的主要目的是提供安全的远程登录、文件传输以及端口转发等功能,广泛应用于需要在Java应用程序中进行安全通信的场景...

    基于Java的用Java写的SFTP代码.zip

    9. **代码示例**:解压"用java写的SFTP代码.zip",你会找到一个示例程序,它展示了如何使用JSch库进行SFTP操作。通过阅读和理解这个代码,你可以学习如何在实际项目中集成SFTP功能。 总之,Java和JSch库结合为开发...

    java通过sftp模式实现FTP的文件上传下载删除功能

    在Java中,我们可以使用第三方库如JSch(Java Secure Channel)来实现SFTP功能。JSch是一个轻量级的SSH2库,能够提供SSH2协议下的连接、SFTP文件传输等功能。 三、JSch库的使用 1. 添加依赖:首先,你需要在项目中...

    Android实现使用sftp下载linux服务器上的图片文件源码

    2. **建立SSH连接**:使用JSch库,首先需要创建一个`JSch`实例,然后通过`Session.connect()`方法建立到Linux服务器的SSH连接。连接参数包括服务器地址、端口号(默认为22)、用户名和密码。 3. **创建SFTP会话**:...

    java sftp文件上传代码

    在Java中,我们通常使用第三方库如JSch来实现SFTP功能。JSch是一个纯Java实现的SSH2库,它支持SFTP、SCP和SSH会话。下面我们将详细介绍如何使用JSch库进行SFTP文件上传。 1. **JSch库的引入** 首先,你需要在项目...

Global site tag (gtag.js) - Google Analytics