ChannelSftpFactory.java 4.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
package cn.timer.api.aspect;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

/**
 * @author wuqingjun
 * @email 284718418@qq.com
 * @date 2021/12/28
 */
@Slf4j
public class ChannelSftpFactory extends BasePooledObjectFactory<ChannelSftp> {


    public ChannelSftpFactory(String host, Integer port, String protocol, String username, String password,
                              String sessionStrictHostKeyChecking, Integer sessionConnectTimeout, Integer channelConnectedTimeout) {
        super();
        this.host = host;
        this.port = port;
        this.protocol = protocol;
        this.username = username;
        this.password = password;
        this.sessionStrictHostKeyChecking = sessionStrictHostKeyChecking;
        this.sessionConnectTimeout = sessionConnectTimeout;
        this.channelConnectedTimeout = channelConnectedTimeout;
    }
    // host
    private String host;
    // 端口
    private Integer port;
    // 协议
    private String protocol;
    // 用户
    private String username;
    // 密码
    private String password;

    private String sessionStrictHostKeyChecking;
    // session超时时间
    private Integer sessionConnectTimeout;
    // channel超时时间
    private Integer channelConnectedTimeout;

    // 设置第一次登陆的时候提示,可选值:(ask | yes | no)
    private static final String SESSION_CONFIG_STRICT_HOST_KEY_CHECKING = "StrictHostKeyChecking";

    @Override
    public ChannelSftp create() throws Exception {
        return null;
    }

    @Override
    public PooledObject<ChannelSftp> makeObject() throws Exception {
        JSch jsch = new JSch();
        //log.info("sftp尝试连接[" + username + "@" + host + "], use password[" + password + "]");
        Session session = createSession(jsch, host, username, port);
        session.setPassword(password);
        session.connect(sessionConnectTimeout);
        //log.info("sftp已连接到:{}", host);
        Channel channel = session.openChannel(protocol);
        channel.connect(channelConnectedTimeout);
        //log.info("sftp创建channel:{}", host);
        return new DefaultPooledObject<ChannelSftp>((ChannelSftp) channel);
    }

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

    @Override
    public void destroyObject(PooledObject<ChannelSftp> sftpPooled) throws Exception {
        ChannelSftp sftp = sftpPooled.getObject();
        try {
            if (sftp != null) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                } else if (sftp.isClosed()) {
                    log.info("sftp连接已关闭");
                }
                if (null != sftp.getSession()) {
                    sftp.getSession().disconnect();
                }
            }
        } catch (JSchException e) {
            log.error("关闭sftp连接失败: {}", e);
            e.printStackTrace();
            throw new Exception("关闭sftp连接失败");
        }
    }

    @Override
    public boolean validateObject(PooledObject<ChannelSftp> sftpPooled) {
        try {
            ChannelSftp sftp = sftpPooled.getObject();
            if (sftp != null) {
                return (sftp.isConnected() && sftp.getSession().isConnected());
            }
        } catch (JSchException e) {
            log.error("sftp连接校验失败: {}", e);
            e.printStackTrace();
            throw new RuntimeException("sftp连接校验失败");
        }
        return false;
    }

    /**
     * 创建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 RuntimeException(host + " sftp建立连接session is null");
        }
        session.setConfig(SESSION_CONFIG_STRICT_HOST_KEY_CHECKING, sessionStrictHostKeyChecking);
        return session;
    }
}