자바에서 ssh를 활용해서 다른 서버로 접속하여 명령어를 실행해야 되는 경우가 있었다.
이럴때는 jsch를 활용하면 쉽게 사용이 가능하다.
Jsch를 활용한 개념은 3단계로 이루어 진다.
1. Jsch 클래스를 생성한다.
2. ssh를 통해서 연결한다.
3. 원하는 행위를 연결한 서버로 전송한다.
간단하게 먼저 연결하는 예제를 살펴보자.
import java.io.InputStream;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;
public class SFTPSender {
public static void connect() throws Exception{
JSch jsch = new JSch();
Session session = jsch.getSession(접속아이디, 주소, 포트);
session.setPassword(비밀번호);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(); //연결 시도
System.out.println(session);
session.disconnect();
}
}
간단하게 연결하는 코드이다.
저렇게 연결한 뒤에 세션에서 채널을 선택하고, 선택된 채널에서 무엇을 할 지 정하면 된다.
그러면 명령어를 전송하는 코드를 만들어보자.
import java.io.InputStream;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;
public class SFTPSender {
public static void order() throws Exception{
JSch jsch = new JSch();
Session session = jsch.getSession(접속아이디, 주소, 포트);
session.setPassword(비밀번호);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(); //연결
Channel channel = session.openChannel("exec"); //채널접속
ChannelExec channelExec = (ChannelExec) channel; //명령 전송 채널사용
channelExec.setPty(true);
channelExec.setCommand("netstat -tnlp"); //내가 실행시킬 명령어를 입력
//콜백을 받을 준비.
StringBuilder outputBuffer = new StringBuilder();
InputStream in = channel.getInputStream();
((ChannelExec) channel).setErrStream(System.err);
channel.connect(); //실행
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
outputBuffer.append(new String(tmp, 0, i));
if (i < 0) break;
}
if (channel.isClosed()) {
System.out.println("결과");
System.out.println(outputBuffer.toString());
channel.disconnect();
}
}
}
}
채널을 오픈할 때 exec를 매개변수로 하여서 생성하였다.
그리고서는 명령을 connect 메소드를 통해서 실행하였다.
그러면 파일을 받는 것은 어떻게 할까?
해당 채널을 오픈할 때의 내용을 변경하여주면 가능하다.
import java.io.*;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;
public class SFTPSender {
public static void download() throws Exception{
JSch jsch = new JSch();
Session session = jsch.getSession(접속아이디, 주소, 포트);
session.setPassword(비밀번호);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(); //연결 시도
ChannelSftp channelSftp = null;
InputStream in = null;
Channel channel = null;
try{
channel = session.openChannel("sftp"); //방식설정
channel.connect();
channelSftp = (ChannelSftp) channel;
channelSftp.cd("파일을받을디렉토리"); //해당 디렉토리 이동
in = channelSftp.get("파일명"); //파일을 받는다.
}catch (Exception e) {
e.printStackTrace();
}
channel.disconnect();
}
}
명령을 전달한 뒤에 내용을 받는 구간이 없어서 그런지 코드가 더 훨씬 깔끔하다.
cd라는 메소드를 통해서 파을을 받을 곳으로 이동한 뒤에 get메소드를 호출해서 쉽게 가능 하다.
그렇다면 위 코드를 조금만 수정하면 파일 보내는 것도 가능 하다.
import java.io.*;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;
public class SFTPSender {
public static void download() throws Exception{
JSch jsch = new JSch();
Session session = jsch.getSession(접속아이디, 주소, 포트);
session.setPassword(비밀번호);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(); //연결 시도
ChannelSftp channelSftp = null;
InputStream in = null;
Channel channel = null;
try{
channel = session.openChannel("sftp"); //방식설정
channel.connect();
channelSftp = (ChannelSftp) channel;
//put을 통해서 파일을 보낸다.
//SftpProgressMonitor 인터페이스를 굳이 사용하지 않아도 된다!!
channelSftp.put("전송할디렉토리+파일명칭", "받을디렉토리+파일명칭", 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); // 프로그래스
}
return true; //false인경우 count 메소드가 동작하지 않는다.
}
});
}catch (Exception e) {
e.printStackTrace();
}
channel.disconnect();
}
}
파일을 전송하는 것도 put이라는 메소드를 통해서 쉽게 가능하다.
눈여겨 보아야할 점이 SftpSftpProgressMonitor 인터페이스를 통해서 콜백행위를 알 수 있게 해준다는 점 이다.
시작, 종료, 프로그래스 관련된 내용이 확인 가능 하다.
라이브러리 추가는 maven과 gradle 둘 다 가능하다.
* 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'
maven 리파지토리를 방문해서 원하는 버전과 스펙을 확인하자!
아니면 검색하면 해당 홈페이지에서도 받을 수 있다.
* 추가
- 윈도우 서버에서는 ssh관련된 접속이 잘(매우) 안된다..
- 요 2가지 방식, 리눅스 -> 리눅스, 윈도우 -> 리눅스 는 잘 되는데 목적지가 윈도우면 정말 잘 안된다.
'Java(자바)' 카테고리의 다른 글
파일 복사하기, Blob데이터를 파일로 만들기 (0) | 2019.04.25 |
---|---|
Java로 File 만든 날짜 보기 (0) | 2019.04.25 |
자바 함수형 프로그래밍 (0) | 2019.04.25 |
Java에서 배열형태 문자를 배열로 만들기 (0) | 2019.04.25 |
AOP를 일반자바 프로젝트에서도 해보자 (0) | 2019.04.25 |
댓글