使用的jar包:java
1 <dependency> 2 <groupId>com.jcraft</groupId> 3 <artifactId>jsch</artifactId> 4 <version>0.1.54</version> 5 </dependency>
文件上傳也可使用scp,可是最後實現發現scp特別困難,並且只能實現上傳這一個功能。若是要實現文件的刪除則須要使用其餘命令。spring
而sftp則是創建一個ssh通道,而後能夠很方便的在通道內執行一系列命令,如put, get, rm, mkdir, rmdir,從而能夠方便的管理遠程服務器的文件。服務器
下面介紹下Java實現。session
首先咱們建立一個pojo,將全部的帳號信息及遠程服務器信息都封裝一下。app
1 package com.snow.sftp; 2 3 import lombok.Data; 4 5 @Data 6 public class SftpAuthority { 7 private String host; // 服務器ip或者主機名 8 private int port; // sftp端口 9 private String user; // sftp使用的用戶 10 private String password; // 帳戶密碼 11 private String privateKey; // 私鑰文件名 12 private String passphrase; // 私鑰密鑰 13 14 public SftpAuthority(String user, String host, int port) { 15 this.host = host; 16 this.port = port; 17 this.user = user; 18 } 19 }
在創建sftp通道過程當中咱們能夠選擇使用用戶名密碼的方式,也能夠選擇使用私鑰(私鑰能夠有密鑰)的方式。ssh
創建一個service interfaceide
1 package com.snow.sftp; 2 3 public interface SftpService { 4 5 void createChannel(SftpAuthority sftpAuthority); 6 7 void closeChannel(); 8 9 boolean uploadFile(SftpAuthority sftpAuthority, String src, String dst); 10 11 boolean removeFile(SftpAuthority sftpAuthority, String dst); 12 13 }
具體實現:this
1 package com.snow.sftp; 2 3 import com.jcraft.jsch.Channel; 4 import com.jcraft.jsch.ChannelSftp; 5 import com.jcraft.jsch.JSch; 6 import com.jcraft.jsch.JSchException; 7 import com.jcraft.jsch.Session; 8 import com.jcraft.jsch.SftpException; 9 import lombok.extern.slf4j.Slf4j; 10 import org.springframework.stereotype.Service; 11 12 import java.util.Properties; 13 14 @Slf4j 15 @Service(value = "sftpService") 16 public class SftpServiceImpl implements SftpService { 17 18 private Session session; 19 private Channel channel; 20 private ChannelSftp channelSftp; 21 22 @Override 23 public void createChannel(SftpAuthority sftpAuthority) { 24 try { 25 JSch jSch = new JSch(); 26 session = jSch.getSession(sftpAuthority.getUser(), sftpAuthority.getHost(), sftpAuthority.getPort()); 27 28 if (sftpAuthority.getPassword() != null) { 29 // 使用用戶名密碼建立SSH 30 session.setPassword(sftpAuthority.getPassword()); 31 } else if (sftpAuthority.getPrivateKey() != null) { 32 // 使用公私鑰建立SSH 33 jSch.addIdentity(sftpAuthority.getPrivateKey(), sftpAuthority.getPassphrase()); 34 } 35 36 Properties properties = new Properties(); 37 properties.put("StrictHostKeyChecking", "no"); // 主動接收ECDSA key fingerprint,不進行HostKeyChecking 38 session.setConfig(properties); 39 session.setTimeout(0); // 設置超時時間爲無窮大 40 session.connect(); // 經過session創建鏈接 41 42 channel = session.openChannel("sftp"); // 打開SFTP通道 43 channel.connect(); 44 channelSftp = (ChannelSftp) channel; 45 } catch (JSchException e) { 46 log.error("create sftp channel failed!", e); 47 } 48 } 49 50 @Override 51 public void closeChannel() { 52 if (channel != null) { 53 channel.disconnect(); 54 } 55 56 if (session != null) { 57 session.disconnect(); 58 } 59 } 60 61 @Override 62 public boolean uploadFile(SftpAuthority sftpAuthority, String src, String dst) { 63 if (channelSftp == null) { 64 log.warn("need create channelSftp before upload file"); 65 return false; 66 } 67 68 if (channelSftp.isClosed()) { 69 createChannel(sftpAuthority); // 若是被關閉則應從新建立 70 } 71 72 try { 73 channelSftp.put(src, dst, ChannelSftp.OVERWRITE); 74 log.info("sftp upload file success! src: {}, dst: {}", src, dst); 75 return true; 76 } catch (SftpException e) { 77 log.error("sftp upload file failed! src: {}, dst: {}", src, dst, e); 78 return false; 79 } 80 } 81 82 @Override 83 public boolean removeFile(SftpAuthority sftpAuthority, String dst) { 84 if (channelSftp == null) { 85 log.warn("need create channelSftp before remove file"); 86 return false; 87 } 88 89 if (channelSftp.isClosed()) { 90 createChannel(sftpAuthority); // 若是被關閉則應從新建立 91 } 92 93 try { 94 channelSftp.rm(dst); 95 log.info("sftp remove file success! dst: {}", dst); 96 return true; 97 } catch (SftpException e) { 98 log.error("sftp remove file failed! dst: {}", dst, e); 99 return false; 100 } 101 } 102 103 }
調用示例:spa
1 package com.snow.sftp; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class TestSftp { 7 8 public static void main(String[] args) { 9 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"sftp-application-context.xml"}); 10 11 // 用戶名密碼方式 12 SftpService sftpService = context.getBean(SftpService.class); 13 SftpAuthority sftpAuthority = new SftpAuthority("user", "ip or host", port); 14 sftpAuthority.setPassword("user password"); 15 16 sftpService.createChannel(sftpAuthority); 17 sftpService.uploadFile(sftpAuthority, "/home/snow/test/test.png", "/user/testaaa.png"); 18 sftpService.removeFile(sftpAuthority, "/user/testaaa.png"); 19 sftpService.closeChannel(); 20 21 // 公私鑰方式 22 sftpAuthority = new SftpAuthority("user", "ip or host", port); 23 sftpAuthority.setPrivateKey("your private key full path"); 24 sftpAuthority.setPassphrase("private key passphrase"); 25 sftpService.createChannel(sftpAuthority); 26 sftpService.uploadFile(sftpAuthority, "/home/snow/test/test.png", "/user/testaaa.png"); 27 sftpService.removeFile(sftpAuthority, "/user/testaaa.png"); 28 sftpService.closeChannel(); 29 } 30 31 }
除了本文介紹的put和rm操做之外,channelSftp還有不少其它的操做,好比get, mkdir, lcd, rename, rmdir, ls, lstat等,你們能夠自行探索。code