728x90
반응형

sftp를 활용하기 위해서는 JSCH 라이브러리가 필요하다.

라이브러리 버전은 자신에게 알맞는 버전을 받도록 하자.

 

* maven 형태

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

* gradle 형태

// https://mvnrepository.com/artifact/com.jcraft/jsch
compile group: 'com.jcraft', name: 'jsch', version: '0.1.55'

 

사용법은 어렵지 않다. 오히려 파일을 다운받는 기능이나 아니면 명령을 전달해서 결과를 받는 것이 더 복잡하다.

세션을 열어주고 세션 객체를 가져온다.

import java.time.LocalDateTime;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpProgressMonitor;

public class SFTPSender {
    private String ADDRESS = "접속할주소";
    private int PORT = 22;  //포트번호
    private String USERNAME = "아이디";
    private String PASSWORD = "비밀번호";
    private static Session session = null;
    private static Channel channel = null;
    private static ChannelSftp channelSftp = null;

    public void sshAccess() throws Exception {
        JSch jsch = new JSch();
        session = jsch.getSession(USERNAME, ADDRESS, PORT);  //세션 오픈!
        session.setPassword(PASSWORD);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
    }
}

 

위 sshAccess 메소드가 세션객체를 가져오는 부분이다.

해당 세션이 열리게 되면 세션에서 어떠한 체널을 사용 할 지 결정을 하고 파일을 전송하는 메소드만 호출하면 된다.

아래 메소드에서 간단하게 put 메소드만 호출하면 파일을 원하는 경로까지 잘 배달하여준다.

물론 아래 코드는 Exception을 던지고 있기 때문에 try - catch - finally 로 바꾸어 커넥션을 사용하지 않는다면 닫아주는 코드로 바꾸어야한다.

    //..생략
    public void sendFileToOtherServer(String sourcePath, String destinationPath) throws Exception {
        channel = session.openChannel("sftp");
        channel.connect();
        channelSftp = (ChannelSftp) channel;
        channelSftp.put(sourcePath, destinationPath);  //파일을 전송하는 메소드
        channelSftp.disconnect();
        channel.disconnect();
    }	 

 

재미있는 기능 중 1가지는 SftpProgressMonitor 라는 인터페이스를 통해서 파일전송 진행현황(프로그래스, Progress)을 볼 수 있다.

//SftpProgressMonitor 인터페이스 정의 모습 ----
package com.jcraft.jsch;

public interface SftpProgressMonitor{
  public static final int PUT=0;
  public static final int GET=1;
  public static final long UNKNOWN_SIZE = -1L;
  void init(int op, String src, String dest, long max);
  boolean count(long count);
  void end();
}

 

위 인터페이스를 상속받아서 파일을 전송하는 put 메소드의 3번째 인자값으로 전달해주면 동작한다.

    //..생략
    public void sendFileToOtherServer(String sourcePath, String destinationPath) throws Exception {
        channel = session.openChannel("sftp");
        channel.connect();
        channelSftp = (ChannelSftp) channel;
        channelSftp.put(sourcePath, destinationPath, new SftpProgressMonitor() {
            private long max = 0;  //최대
            private long count = 0;  //계산을 위해 담아두는 변수
            private long percent = 0;  //퍼센트
            @Override
            public void init(int op, String src, String dest, long max) {  //설정
                this.max = max;
            }
            @Override
            public void end() {
                //종료시 할 행동
            }
            @Override
            public boolean count(long bytes) {
                this.count += bytes;  //전송한 바이트를 더한다.
                long percentNow = this.count*100/max;  //현재값에서 최대값을 뺀후
                if(percentNow>this.percent){  //퍼센트보다 크면
                    this.percent = percentNow;
                    System.out.println("progress : " + this.percent); //Progress
                }
                return true;//기본값은 false이며 false인 경우 count메소드를 호출하지 않는다.
            }
        });
        channelSftp.disconnect();
        channel.disconnect();
    }	 

 

최종 클래스 모습이다.

import java.time.LocalDateTime;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpProgressMonitor;

public class SFTPSender {
    private String ADDRESS = "접속할주소";
    private int PORT = 22;  //포트번호
    private String USERNAME = "아이디";
    private String PASSWORD = "비밀번호";
    private static Session session = null;
    private static Channel channel = null;
    private static ChannelSftp channelSftp = null;


    public static void main(String[] args) {
        System.out.println("start : " + LocalDateTime.now());
        SFTPSender sender = new SFTPSender();

        try {
            sender.sshAccess();
        } catch (Exception e) {
            e.printStackTrace();
        }
		
        if(session != null){
            try {
                sender.sendFileToOtherServer("D:/보낼파일.txt", "/home/user/test/받을파일.txt");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("end : "  + LocalDateTime.now());
        System.exit(0);
    }



    public void sshAccess() throws Exception {
        JSch jsch = new JSch();
        session = jsch.getSession(USERNAME, ADDRESS, PORT);  //세션 오픈!
        session.setPassword(PASSWORD);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
    }
    public void sendFileToOtherServer(String sourcePath, String destinationPath) throws Exception {
        channel = session.openChannel("sftp");
        channel.connect();
        channelSftp = (ChannelSftp) channel;
        channelSftp.put(sourcePath, destinationPath);  //파일을 전송하는 메소드
        channelSftp.disconnect();
        channel.disconnect();
    }	 

    public void sendFileToOtherServer(String sourcePath, String destinationPath) throws Exception {
        channel = session.openChannel("sftp");
        channel.connect();
        channelSftp = (ChannelSftp) channel;
        channelSftp.put(sourcePath, destinationPath, new SftpProgressMonitor() {
            private long max = 0;  //최대
            private long count = 0;  //계산을 위해 담아두는 변수
            private long percent = 0;  //퍼센트
            @Override
            public void init(int op, String src, String dest, long max) {  //설정
                this.max = max;
            }
            @Override
            public void end() {
                //종료시 할 행동
            }
            @Override
            public boolean count(long bytes) {
                this.count += bytes;  //전송한 바이트를 더한다.
                long percentNow = this.count*100/max;  //현재값에서 최대값을 뺀후
                if(percentNow>this.percent){  //퍼센트보다 크면
                    this.percent = percentNow;
                    System.out.println("progress : " + this.percent); //Progress
                }
                return true;//기본값은 false이며 false인 경우 count메소드를 호출하지 않는다.
            }
        });
        channelSftp.disconnect();
        channel.disconnect();
    }	 
}

 

sftp로 파일을 전송하기 때문에 용량이 큰 파일(2GB 이상) 같은 파일도 전송이 가능하다.

실제 동작모습

 

참조 : https://lts0606.tistory.com/256

728x90
반응형

+ Recent posts