spring boot 에서 sftp 사용하기 (삽질)
아니 찾아보면 볼수록 java 에서 sftp 를 쓰는게 이렇게 복잡하고 어려운일인가.. 싶다.
머가 이렇게 방법이 많은지... ㅠㅠ
일단 spring 에서 지원하고 있는 방법이 있는거 같아서 시도해보자.
내 심플한 상상으로는 IP, Id , Pass 이용하여 클라이언트 객체를 선언하고
파일 Path 를 파라메터로 받아서 Upload 했으면 좋겠는데..
아무래도 그 외에 sftp 프로토콜에서 지원해야하는 많은 인터페이스를 구현해야 라이브러리가 될테니 복잡해지고 있는게 아닌가 싶다.
어쨌거나 난 그냥 단순히 업로드만 되면 OK 인 상황이니 최대한 간단하게 해보자
일단 젤 잘 설명되어있는것 같은 사이트로 트라이 시작!
blog.pavelsklenar.com/spring-integration-sftp-upload-example/
# 현재 Gradle 프로젝트에서 사용하는 boot 버전
'org.springframework.boot' version '2.1.17.RELEASE'
1. 이거에 맞는 버전을 찾아보니 5.1.13 인거 같아서 build.gradle 에 추가
compile group: 'org.springframework.integration', name: 'spring-integration-sftp', version: '5.1.13.RELEASE'
2. 이제 환경설정
config/SftpConfig.java 에 파일 추가
그리고 junit 클래스 로 테스트
package com.crizen.util;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import com.crizen.config.SftpConfig.UploadGateway;
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:/test.yml")
public class SftpTest {
@Autowired
private UploadGateway gateway;
private static Path sftpFolder;
@Test
public void testUpload() throws IOException {
// Prepare phase
Path tempFile = Files.createTempFile("UPLOAD_TEST", ".csv");
// test phase
gateway.upload(tempFile.toFile());
}
}
음 일단 동작은 한다. 하지만 먼가 복잡하다. 난 Util 처럼 이용하고 싶다. 로그를 보니 결국 jscsh 라이브러리를 사용하는 것으로 보인다. 그럼 굳이... 복잡하게 쓸 이유가 없을것 같다.
======================================================================
다시 검색 시작
www.programmersought.com/article/63481170477/
오 이게 심플해 보인다.
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
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;
public class SftpUtil {
// Set the prompt when logging in for the first time. Optional value: (ask | yes | no)
private static final String SESSION_CONFIG_STRICT_HOST_KEY_CHECKING = "StrictHostKeyChecking";
String host ="";
String username ="";
String password = "";
String root = "/home/";
int port = 22;
int timeout = 15000;
public SftpUtil(String host , String username , String password)
{
this.host = host;
this.username = username;
this.password = password;
}
private ChannelSftp createSftp() throws Exception {
JSch jsch = new JSch();
Session session = createSession(jsch, host, username, port);
session.setPassword(password);
session.connect(timeout);
Channel channel = session.openChannel("sftp");
channel.connect(timeout);
return (ChannelSftp) channel;
}
private Session createSession(JSch jsch, String host, String username, Integer port) throws Exception {
Session session = null;
if (port <= 0) {
session = jsch.getSession(username, host);
} else {
session = jsch.getSession(username, host, port);
}
if (session == null) {
throw new Exception(host + " session is null");
}
session.setConfig(SESSION_CONFIG_STRICT_HOST_KEY_CHECKING, "no");
return session;
}
private void disconnect(ChannelSftp sftp) {
try {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
} else if (sftp.isClosed()) {
}
if (null != sftp.getSession()) {
sftp.getSession().disconnect();
}
}
} catch (JSchException e) {
e.printStackTrace();
}
}
public boolean uploadFile(String targetPath, File file) throws Exception {
return this.uploadFile(targetPath, new FileInputStream(file));
}
private boolean uploadFile(String targetPath, InputStream inputStream) throws Exception {
ChannelSftp sftp = this.createSftp();
try {
sftp.cd(root);
int index = targetPath.lastIndexOf("/");
String fileName = targetPath.substring(index + 1);
sftp.put(inputStream, fileName);
return true;
} catch (Exception e) {
throw new Exception("Upload File failure");
} finally {
this.disconnect(sftp);
}
}
public static void main(String[] args) {
SftpUtil ftp = new SftpUtil("아이피", "아이디", "비번");
File file = new File("C:\\test.xml");
try {
ftp.uploadFile("/test.xml", file);
} catch (Exception e) {
e.printStackTrace();
}
}
오! 딱 상상하던데로이다. 잘 동작한다