반응형

파일을 생성 후, 전송을 해줘야하는 경우 sftp 프로토콜 방식을 사용하여 파일을 전송해줘야 하는 경우가 있는데, Jsch를 사용하면 쉽게 연결하여 전송 할 수 있고, 전송간의 상태등을 callback을 통해 받을 수 있습니다.

 

SFtp 전송하기

먼저 jsch를 추가합니다.

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>

 

App.java

package com.psw.file.sftp;

import org.apache.log4j.Logger;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

public class App {
	
	private static final Logger logger = Logger.getLogger(App.class);
	
	private static String OUTPUT_FILE_PATH = "파일경로";
	private static String DESTINATION_PATH = "전송경로";
	private static String fileName = "파일명";
	private static String REMOTE_ADDR = "전송지 ip";
	private static int PORT = 포트;
	private static String USERNAME = "계정";
	private static String PASSWORD = "비밀번호";
	
	private static Session session = null;
	private static Channel channel = null;
	private static ChannelSftp channelSftp = null;
	
	public static void main( String[] args ){
		logger.info("======= sftp send start =======");
		JSch jsch = new JSch();
		try {
			session  = jsch.getSession(USERNAME, REMOTE_ADDR, PORT);
			session.setPassword(PASSWORD);
			java.util.Properties config = new java.util.Properties();
			config.put("StrictHostKeyChecking", "no");
			session.setConfig(config);
			session.connect();
			
			channel = session.openChannel("sftp");
			channel.connect();
			channelSftp = (ChannelSftp) channel;
			String filePath = OUTPUT_FILE_PATH + fileName;
			String DestinyPath = DESTINATION_PATH + fileName;
			channelSftp.put(filePath, DestinyPath);
		} catch (JSchException e) {
			logger.error("JSchException", e);
		} catch (SftpException e1) {
			logger.error("SftpException", e1);
		} finally {
			if(channelSftp != null) channelSftp.disconnect();
			if(channel != null) channel.disconnect();
			if(session != null) session.disconnect();
			
			logger.info("======= sftp send end =======");
		}
	}
}

접속시 호스트키값을 사용하지 않기에 config값에 StrictHostKeyChecking을 no 옵션으로 처리합니다.

(사용하실 분들은 yes)

 

연결할 채널은 sftp로 연결이므로 sftp로 열어주고 연결 합니다.

 

전송할 파일의 경로와 전송지 경로와 파일명 설정하고 전송을 시작합니다.

간단한 전송 예제를 확인해봤습니다.

 

 

진행상태 콜백 받기 외 옵션 설정

ChannelSftp 클래스에 대해 좀 더 알아보자면, 전송시 처리하는 put메소드 파라미터에 따라 옵션을 변경할 수 있고 전송진행상태를 확인 할 수 있습니다.

진행상태는 SftpProgressMonitor() 인터페이스를 상속받

put(src, dst) : 덮어쓰기

put(src, dst, 1) : 파일이 존재하면 동작하지 않음

put(src, dst, new SftpProgressMonitor(){
      ...
});

channelSftp.put(filePath, DestinyPath, new SftpProgressMonitor() {

	public void init(int op, String src, String dest, long max) {
		// TODO Auto-generated method stub
	}

	public boolean count(long count) {
		// TODO Auto-generated method stub
		return false;
	}

	public void end() {
		// TODO Auto-generated method stub
	}
});

 - init

   op : 전송 방향 (put or get)

   src : 전송 파일 이름

   dest : 대상 파일 이름

   max : 최종 개수

 

- count

  count : 지금까지 전송 된 바이트수

  계속 전송을 해야하면 return true, 취소해야하는경우 false 처리

- end

  모든 데이터가 전송되었거나 취소되면 호출 

 

 

진행상태 확인하기

package com.psw.file.sftp;

import org.apache.log4j.Logger;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

public class App {
	
	private static final Logger logger = Logger.getLogger(App.class);
	
	private static String OUTPUT_FILE_PATH = "파일경로";
	private static String DESTINATION_PATH = "전송경로";
	private static String fileName = "파일명";
	private static String REMOTE_ADDR = "전송지 ip";
	private static int PORT = 포트;
	private static String USERNAME = "계정";
	private static String PASSWORD = "비밀번호";
	
	private static Session session = null;
	private static Channel channel = null;
	private static ChannelSftp channelSftp = null;
	
	public static void main( String[] args ){
		logger.info("======= sftp send start =======");
		JSch jsch = new JSch();
		
		try {
			session  = jsch.getSession(USERNAME, REMOTE_ADDR, PORT);
			session.setPassword(PASSWORD);
			java.util.Properties config = new java.util.Properties();
			config.put("StrictHostKeyChecking", "no");
			session.setConfig(config);
			session.connect();
			
			channel = session.openChannel("sftp");
			channel.connect();
			channelSftp = (ChannelSftp) channel;
			String filePath = OUTPUT_FILE_PATH + fileName;
			String DestinyPath = DESTINATION_PATH + fileName;
			channelSftp.put(filePath, DestinyPath, new SftpProgressMonitor() {
				long FileSize = 0;
				long sendFileSize = 0;
				int per = 0;
				public void init(int op, String src, String dest, long max) {
					this.FileSize = max;
				}
			
				public boolean count(long count) {
					this.sendFileSize += count;
					long p = this.sendFileSize * 100 / this.FileSize;
					if(p > per) {
//						System.out.println(per + "%");
						System.out.print("=");
						per++;
					}
					
					return true;
				}
			
				public void end() {
					// TODO Auto-generated method stub
				}
			});
		} catch (JSchException e) {
			logger.error("JSchException", e);
		} catch (SftpException e1) {
			logger.error("SftpException", e1);
		} finally {
			if(channelSftp != null) channelSftp.disconnect();
			if(channel != null) channel.disconnect();
			if(session != null) session.disconnect();
			System.out.println();
			logger.info("======= sftp send end =======");
		}
	}
}

반응형