본문 바로가기

IT, 인터넷/JAVA, 스프링부트

자바 sftp 명령어 전송 및 파일 전송

반응형

자바에서 sftp 방식으로 명령어를 입력해서 리눅스에 전달을 해서 실행을 해야 하는 경우나,

자바에서 sftp 방식으로 파일을 전송을 해야 하는 경우가 있습니다.

이런 경우에 자바에 jsch 라는 것을 사용을 해서 명령어 실행 및 파일전송이 가능 합니다.

 

이경우 리눅스 서버에서 sftp를 사용 하도록 열어 주어야 가능 하겠죠...

이제 pom.xml 그래들을 설정을 해서 사용 하는 방법을 보겠습니다.

  • pom.xml

<dependency>

    <groupId>com.jcraft</groupId>

    <artifactId>jsch</artifactId>

    <version>0.1.55</version>

</dependency>

 

  • gradle

implements group: 'com.jcraft', name: 'jsch', version: '0.1.55'

 

환경설정이 되었으면 sftp에 명령어 실행 및 파일을 전송할 파일을 만들어 줍니다.

  • SSHUtil.java

import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;

 

import com.jcraft.jsch.Channel;

import com.jcraft.jsch.ChannelExec;

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 SSHUtil {

 

    private Session session;

    private Channel channel;

    private ChannelExec channelExec;

    private ChannelSftp channelSftp;

    private long percent = 0;

   

    public SSHUtil() {}

   

    public SSHUtil(String name, String password, String host, int port) {

        this.connect(name, password, host, port);

    }

   

    public SSHUtil connect(String name, String password, String host, int port) {

        try {

            session = new JSch().getSession(name, host, port);

            session.setPassword(password);

            session.setConfig("StrictHostKeyChecking", "no");

            session.connect();

        } catch (JSchException e) {

            e.printStackTrace();

        }

       

        return this;

    }

   

    public String command(String command) {

        if(session == null) {

            return "ssh 연결이 되지 않았습니다.";

        }else if(command == null || command.trim().equals("")) {

            return "명령어를 입력해주세요.";

        }

       

        String responseString = "";

        try {

            ByteArrayOutputStream responseStream = new ByteArrayOutputStream();

           

            channelExec = (ChannelExec) session.openChannel("exec");

            channelExec.setCommand(command);

            channelExec.setOutputStream(responseStream);

            channelExec.connect();

            while (channelExec.isConnected()) {

                Thread.sleep(100);

            }

           

            responseString = new String(responseStream.toByteArray());

        } catch (JSchException e) {

            e.printStackTrace();

        } catch (InterruptedException e) {

            e.printStackTrace();

        } finally {

            //this.disConnect();

        }

        return responseString;

    }

   

    public String fileSend(String OutPutPath, String DestinyPath) {

        percent = 0; //초기화

        if(session == null) {

            return "ssh 연결이 되지 않았습니다.";

        }else if(OutPutPath == null || DestinyPath == null) {

            return "경로가 정상적으로 등록되지 않았습니다.";

        }

       

        try {

            channelSftp = (ChannelSftp) session.openChannel("sftp");

            channelSftp.connect();

            channelSftp.put(OutPutPath, DestinyPath, new SystemOutProgressMonitor());

        } catch (JSchException e) {

            e.printStackTrace();

        } catch (SftpException e) {

            e.printStackTrace();

        } finally {

            //this.disConnect();

        }

        return "정상적으로 전송하였습니다.";

    }

   

    public void disConnect() {

        if (session != null) {

            session.disconnect();

        }

        if (channel != null) {

            channel.disconnect();

        }

        if(channelExec != null) {

            channelExec.disconnect();

        }

        if(channelSftp != null) {

            channelSftp.disconnect();

        }

    }

   

    public long getSendPercent() {

        if(percent >= 100) {

            percent = 0;

            return (long)100;

        }

        return percent;

    }

   

    class SystemOutProgressMonitor implements SftpProgressMonitor {

        private long fileSize = 0;

        private long sendFileSize = 0;

       

        @Override

        public void init(int op, String src, String dest, long max) {

            this.fileSize = max;

            System.out.println("Starting : " + op + "  " + src + " -> " + dest + " total : " + max);

        }

 

        @Override

        public boolean count(long count) {

            this.sendFileSize += count;

            long p = this.sendFileSize * 100 / this.fileSize;

            if(p > percent) {

                percent++;

            }

            return true;

        }

 

        @Override

        public void end() {

            System.out.println("Finished!");

        }

    }

}

 

이렇게 추가를 하였으면 이제 실행을 하면 됩니다.

스프링부트 프로젝트를 로컬에서 하면 임시 폴더를 만들어서 거기에 파일을 옮기고 올리면 되지만,

운영에 jar나 war 처럼 올려 버리면 파일을 inputstream으로만 읽기만 되기 때문에

파일을 생성을 임의의 폴더에 해야 합니다.

저같은 경우에는 로컬은 c 드라이브에 운영은 임의 폴더를 만들어서 테스트를 하였습니다.

  • 로컬

 

  • 운영 (jar나 war 배포)

이렇게 폴더를 임의로 만들어서 여기에 fix(고정) 파일들은 옮겨 놓고, 새로 생성해서 전송을 해야 하는 파일들은

임시 폴더에 생성을 한후에 파일을 보내면 됩니다.

  • 임시 파일 생성

https://astonysia-story.tistory.com/77

 

자바 임시파일 생성후 ftp 업로드

스프링부트로 개발이나 운영에 배포를 할때 jar로 묶어서 배포를 하는 경우가 있습니다. jar로 묶어서 배포 하는 방법 package를 jar로 변경 하여 줍니다. Goals : package 입력후에 run을 하면 jar로 배포

astonysia-story.tistory.com

해당 블로그에

  • 임시파일 생성 을 참고해 주세요

 

  • 자바 파일 실행

public class test {

 

    public static void main(String[] args) {

        SSHUtil ssh = new SSHUtil(아이디, 비밀번호, 호스트, 포트);

       

        // 폴더 생성

        ssh.command("mkdir " + "/root/test");

       

        // 파일 전송 ex) c:/test/test.txt, /root/test/test/txt

        ssh.fileSend(전송할 로컬파일패스.파일명, ftp에 올라갈 파일패스.파일명);

       

        // 종료

        ssh.disConnect();

    }

 

}

반응형