본문 바로가기
Language/JAVA

SFTP구현 / SFTP 개발 / SFTP 정리

by 박살낼겨 2022. 12. 1.

 

필자의 개발목적

 

스케줄러를 사용해 특정 로컬 경로 안의 파일을 

 

다른 서버의 특정 경로에 주기적으로 넣기 위함

 

 

 

 


개발세팅

 

pom.xml

 

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

 

Jsch 사용을 하기위해 Maven Dependency 추가합니다.

※ Jsch를 사용하는 이유

    SSHD(SSH 프로토콜 사용, 연결을 수신 프로토콜의 서버역할 | 사용자 인증, 암호화, 터미널 연결 파일전송 등)

    서버에 연결하여 포트 포워딩, 파일 전송 등을 사용할 수 있다.

 

 

application.properties(스프링부트) 혹은 system.properties

 

server.port=1690

########################접속정보######################################
#Target Server Info
HOST=1.2.3.43
PORT=22
USER_NAME=root
PASSWORD=pass
#Local Test
#HOST=127.0.0.1
#PORT=22
#USER_NAME=BAKSAL
#PASSWORD=1111
################################################################### 

########################파일위치######################################
#TARGET_DIR=/FILE/pa
TARGET_DIR=/root/file/send
#Local Test
#START_DIR=C:/TEST/FILE/gov24SFTP
START_DIR=/root/was/gov24SFTP/FILE 
###################################################################

 

properties에 작성해 두면 소스 개발 시 접속정보, 파일위치 등 공통정보 수정에 용이하다.

 

 

 

 


SFTP 코드

 

package com.controller;

import java.io.File;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RestController;

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;

@RestController
public class SFTPController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    // ================접속정보_application.properties=======================
    @Value("${HOST}")
    private String host;
    
    @Value("${PORT}")
    private int port;
    
    @Value("${USER_NAME}")
    private String username;
    
    @Value("${PASSWORD}")
    private String password;
    
    @Value("${TARGET_DIR}")
    private String targetDir;
    
    @Value("${START_DIR}")
    private String startDir;
    // ===================================================================
    

    @Scheduled(fixedDelay = 5000) // 5초에 한 번씩 수행
    public void sendFile() {
	// 해당 디렉토리 내 파일 검색
	File[] fileList = new File(startDir).listFiles();
	int fileLength = fileList.length;
	if (fileLength > 0) {
	    for (File targerFile : fileList) {
		try {
		    logger.info("====================sftp 전송 시작========================");
		    //JSch 객체 생성
		    JSch jsch = new JSch();
		    
		    //Session 생성, 원격서버에 대한 접속정보
		    Session session = jsch.getSession(username, host, port);
		    session.setPassword(password);
		    
		    // properties 객체생성, StrictHostKeyChecking 이라는 설정값을 no 로 설정
		    Properties config = new Properties();
		    config.put("StrictHostKeyChecking", "no");
		    session.setConfig(config);
		    
		    //서버에 접속 
		    session.connect();
		    
		    //sftp 채널열기
		    Channel channel = session.openChannel("sftp");
		    
		    //원격지에 명령어 호출, 채널을 ssh용 채널 객체로 캐스팅한다.
		    channel.connect();
		    ChannelSftp channelSftp = (ChannelSftp) channel;
		    
		    logger.info("보내는 파일명 : " + String.valueOf(targerFile));
		    channelSftp.put(targerFile.getPath(), targetDir);
		    
		    //채널, 세션 연결해제
		    channel.disconnect();
		    session.disconnect();
		} catch (SftpException e) {
		    logger.info("!!!! 에러발생!!!! : SftpException" + e);
		} catch (JSchException e1) {
		    logger.info("!!!! 에러발생!!!! : JSchException" + e1);
		} finally {
		    // 전송완료 후 파일 삭제
		    targerFile.delete();
		    
		    logger.info("====================sftp 전송 완료========================");
		}
	    }
	}
     }
    
}

 

 

!!! 소스리뷰 !!!

 

Start 디렉토리 안에 파일 존재여부 확인 후 있으면 반복문을 통해 모두 Target 디렉토리로 보낸다.

 

라는 목적에 맞게 개발이 됐다.

 

 

개발하고 보니 생각보다 간단하다.

 

서버 간 방화벽, 커넥션의 문제 해결이 어려웠지 사실 소스 개발은 반나절도 걸리지 않았다.

 

 

 


SFTP 코드 간단 정리

 

1. Jsch의 라이브러리를 사용한다.

JSch jsch = new JSch();

 

2. 원격으로 붙고자하는 서버에 Session으로 사용자인증 후

Session session = jsch.getSession(username, host, port);
session.setPassword(password);

 

3. Session에 connect(접속)

session.connect();

 

4. SFTP Channel 열기

Channel channel = session.openChannel("sftp");  

 

5. ChannelSftp를 사용해 특정 디렉토리에 원하는 파일 put

ChannelSftp channelSftp = (ChannelSftp) channel;
channelSftp.put(targerFile.getPath(), targetDir);

 

6. Channel, Session 모두 disconnect(접속종료)

channel.disconnect();
session.disconnect();