將本地文件利用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方法調用測試

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