将本地文件利用sftp上传至目标服务器

第一步,导包

		<!-- sftp -->
		<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
		<dependency>
			<groupId>com.jcraft</groupId>
			<artifactId>jsch</artifactId>
			<version>0.1.54</version>
		</dependency>

第二步,创建sftpConfig的实体类

    //密钥地址 
    private String privateKeyPath;
    //口令
    private String passphrase;
    //目标服务器ip
    private String ip;
    //目标服务器端口号
    private Integer port;
    //目标服务器用户名(root)
    private String username;
    //目标服务器登录密码
    private String pwd;
    
    private String path;
    
    private String baseDir;

第三步,创建SftpChannel,以密钥或者用户密码登录目标服务器

我这里用的账号密码登录目标服务器,同时给出密钥登录方式
public class SftpChannel {
	Session session = null;
	Channel channel = null;

	// 端口默认为22
	public static final int SFTP_DEFAULT_PORT = 22;

	/** 利用JSch包实现SFTP下载、上传文件(秘钥方式登陆) */
	public ChannelSftp connectByIdentity(SftpConfig sftpConfig) throws JSchException {
		JSch jsch = new JSch();
		int port = SFTP_DEFAULT_PORT;
		// 设置密钥和密码
		// 支持密钥的方式登陆,只需在jsch.getSession之前设置一下密钥的相关信息就可以了
		if (StringUtils.isNotBlank(sftpConfig.getPrivateKeyPath())) {
			if (StringUtils.isNotBlank(sftpConfig.getPassphrase())) {
				// 设置带口令的密钥
				jsch.addIdentity(sftpConfig.getPrivateKeyPath(), sftpConfig.getPassphrase());
			} else {
				// 设置不带口令的密钥
				jsch.addIdentity(sftpConfig.getPrivateKeyPath());
			}
		}
		if (sftpConfig.getPort() != null) {
			port = Integer.valueOf(sftpConfig.getPort());
		}
		if (port > 0) {
			// 采用指定的端口连接服务器
			session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), port);
		} else {
			// 连接服务器,采用默认端口
			session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp());
		}
		if (session == null) {
			throw new JSchException("session为空,连接失败");
		}
		Properties sshConfig = new Properties();
		sshConfig.put("StrictHostKeyChecking", "no");
		session.setConfig(sshConfig);
		session.setTimeout(30000);
		session.connect();
		// 创建sftp通信通道
		channel = (Channel) session.openChannel("sftp");
		channel.connect();
		return (ChannelSftp) channel;
	}

	/** 利用JSch包实现SFTP下载、上传文件(用户名密码方式登陆) */
	public ChannelSftp connectByPwd(SftpConfig sftpConfig) throws JSchException {
		JSch jsch = new JSch();
		int port = SFTP_DEFAULT_PORT;
		if (sftpConfig.getPort() != null) {
			port = Integer.valueOf(sftpConfig.getPort());
		}
		System.out.println("目标服务器用户名=" + sftpConfig.getUsername() + "--目标服务器IP=" + sftpConfig.getIp());
		System.out.println("目标服务器密码=" + sftpConfig.getPwd());
		if (port > 0) {
			// 采用指定的端口连接服务器
			session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), port);
		} else {
			// 连接服务器,采用默认端口
			session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp());
		}
		if (session == null) {
			throw new JSchException("session为空,连接失败");
		}
		// 设置登陆主机的密码
		session.setPassword(sftpConfig.getPwd());// 设置密码
		Properties sshConfig = new Properties();
		sshConfig.put("StrictHostKeyChecking", "no");
		session.setConfig(sshConfig);
		session.setTimeout(30000);
		session.connect();
		// 创建sftp通信通道
		channel = (Channel) session.openChannel("sftp");
		channel.connect();
		return (ChannelSftp) channel;
	}
		//上传或下载完成后一定记得调用此方法关闭通道
		public void closeChannel() {
		if (channel != null) {
			channel.disconnect();
		}
		if (session != null) {
			session.disconnect();
		}
	}
}

第四步,上传文件的util

public class SFTPUtil {
	/*
	 * 获取sftp对象
	 */
	 //这里的paran参数相当于构造一个json格式的sftpconfig对象字符串,将其格式化后转为对象
	 //格式"{privateKeyPath:'',passphrase:''}"将sftpconfig的参数注入
	public static SftpConfig getSftpObj(String param) {
		SftpConfig sftpConfig = new SftpConfig();
		if (StringUtils.isNotBlank(param)) {
			JSONObject jsonObj = JSONObject.fromObject(param);
			sftpConfig = (SftpConfig) JSONObject.toBean(jsonObj, SftpConfig.class);
		}
		return sftpConfig;
	}

	/** sftp 上传 */
	public static boolean upload(SftpConfig config, String baseDir, String fileName, String filePath) {
		// logger.info();
		System.out.println("路径:baseDir=" + baseDir);

		SftpChannel sftpChannel = new SftpChannel();
		ChannelSftp sftp = null;
		try {
			if (StringUtils.isNotBlank(config.getPrivateKeyPath())) {
				sftp = sftpChannel.connectByIdentity(config);
			} else {
				sftp = sftpChannel.connectByPwd(config);
			}
			if (sftp.isConnected()) {
				//System.out.println("连接服务器成功");
			} else {
				//System.out.println("连接服务器失败");
				return false;
			}
			// 检查路径
			if (!isExist(sftp, baseDir)) {
				//System.out.println("创建sftp服务器路径失败:" + baseDir);
				return false;
			}
			String dst = baseDir + "/" + fileName;
			String src = filePath + "/" + fileName;

			//System.out.println("开始上传,本地服务器路径:[" + src + "]目标服务器路径:[" + dst + "]");
			sftp.put(src, dst);
			//System.out.println("上传成功"+sftp.toString());
			return true;
		} catch (Exception e) {
			//System.out.println("上传失败" + e);
			return false;
		} finally {
			sftpChannel.closeChannel();
		}
	}
/**
	 * 判断文件夹是否存在 true 目录创建成功,false 目录创建失败
	 * 
	 * @param sftp
	 * @param filePath 文件夹路径
	 * @return
	 */
	public static boolean isExist(ChannelSftp sftp, String filePath) {
		String paths[] = filePath.split("\\/");
		String dir = paths[0];
		for (int i = 0; i < paths.length - 1; i++) {
			dir = dir + "/" + paths[i + 1];
			try {
				sftp.cd(dir);
			} catch (SftpException sException) {
				if (sftp.SSH_FX_NO_SUCH_FILE == sException.id) {
					try {
						sftp.mkdir(dir);
					} catch (SftpException e) {
						e.printStackTrace();
						return false;
					}
				}
			}
		}
		return true;
	}
}

第五步,main方法调用测试

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章