Java(자바)

Java Jsch를 활용하여 파일 다운로드(Jsch sftp, Jsch download file)

마샤와 곰 2019. 10. 23. 08:34

 

 

jsch를 활용해서 파일을 다운로드를 하려면 체널을 연결 할 때 sftp로 연결을 하면 된다.

그리고 나서 연결된 체널을 ChannelSftp 라는 객체로 바꾸어주고 난 뒤에 일반 비지니스 로직을 실행하면 된다.

먼저 연결부분이다.

import java.io.File;
import java.io.InputStream;
import java.util.Vector;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class JschExec {
	
	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 ChannelExec channelExec = null;
	private static ChannelSftp channelSftp = null;
	private static final String PATHSEPARATOR = "/";	
    
         //세션 오픈 메소드
	public boolean sshAccess() throws Exception {
		JSch jsch = new JSch();
		
		jsch.setKnownHosts("/etc/hosts");  //요기 요거!!
		
		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();
		return true;
	}
}    

 

중간에 보면 setKnownHosts라는 메소드를 사용한 부분이 있는데..간혹 리눅스에서 아래 사진과 같은 오류를 내는 경우가 있다.

열리지 않는다는데??

접속하는 이름(명칭, 도메인 또는 ip)을 찾지못하는 오류이므로 hosts 파일이(윈도우는 System폴더) 있는 곳을 지정해 주면된다. 만약 위 사진과 같은 오류가 발생하지 않는다면 해당 메소드는 주석처리해도 된다.

 

마지막으로 다운로드를 구현한 메소드 이다.

    //파일 다운로드
    public void recursiveFolderDownload(String sourcePath, String destinationPath) throws Exception {
		channel = session.openChannel("sftp");
		channel.connect();
		channelSftp = (ChannelSftp) channel;
        Vector<ChannelSftp.LsEntry> fileAndFolderList = channelSftp.ls(sourcePath); // Let list of folder content
        for (ChannelSftp.LsEntry item : fileAndFolderList) {
            if (!item.getAttrs().isDir()) { // 파일체크
                if (!(new File(destinationPath + PATHSEPARATOR + item.getFilename())).exists()
                        || (item.getAttrs().getMTime() > Long
                                .valueOf(new File(destinationPath + PATHSEPARATOR + item.getFilename()).lastModified()
                                        / (long) 1000)
                                .intValue())) { // Download only if changed later.
                    new File(destinationPath + PATHSEPARATOR + item.getFilename());
                    channelSftp.get(sourcePath + PATHSEPARATOR + item.getFilename(),
                            destinationPath + PATHSEPARATOR + item.getFilename()); // 파일 다운로드 하기
                }
            } else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) {
                new File(destinationPath + PATHSEPARATOR + item.getFilename()).mkdirs(); // Empty folder copy.
                recursiveFolderDownload(sourcePath + PATHSEPARATOR + item.getFilename(),
                        destinationPath + PATHSEPARATOR + item.getFilename()); 
            }
        }
    }	

 

내용이 무지 많지만..맨 처음에 만든 sshAccess 메소드를 실행한 뒤에 연결된 세션을 sftp로 바꾸어 이후의 비지니스로직을 수직하는 내용이라 생각하면 될 것 같다.

최종 소스코드라인은 아래처럼 사용하면 된다.

import java.io.File;
import java.io.InputStream;
import java.util.Vector;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class JschExec {
	
	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 ChannelExec channelExec = null;
	private static ChannelSftp channelSftp = null;
	private static final String PATHSEPARATOR = "/";	
    
         //세션 오픈 메소드
	public boolean sshAccess() throws Exception {
		JSch jsch = new JSch();
		
		jsch.setKnownHosts("/etc/hosts");  //요기 요거!!
		
		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();
		return true;
	}
    
    //파일 다운로드
    public void recursiveFolderDownload(String sourcePath, String destinationPath) throws Exception {
		channel = session.openChannel("sftp");
		channel.connect();
		channelSftp = (ChannelSftp) channel;
        Vector<ChannelSftp.LsEntry> fileAndFolderList = channelSftp.ls(sourcePath); // Let list of folder content
        for (ChannelSftp.LsEntry item : fileAndFolderList) {
            if (!item.getAttrs().isDir()) { // 파일체크
                if (!(new File(destinationPath + PATHSEPARATOR + item.getFilename())).exists()
                        || (item.getAttrs().getMTime() > Long
                                .valueOf(new File(destinationPath + PATHSEPARATOR + item.getFilename()).lastModified()
                                        / (long) 1000)
                                .intValue())) { // Download only if changed later.
                    new File(destinationPath + PATHSEPARATOR + item.getFilename());
                    channelSftp.get(sourcePath + PATHSEPARATOR + item.getFilename(),
                            destinationPath + PATHSEPARATOR + item.getFilename()); // 파일 다운로드 하기
                }
            } else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) {
                new File(destinationPath + PATHSEPARATOR + item.getFilename()).mkdirs(); // Empty folder copy.
                recursiveFolderDownload(sourcePath + PATHSEPARATOR + item.getFilename(),
                        destinationPath + PATHSEPARATOR + item.getFilename()); 
            }
        }
    }	    
}    

 

반응형