SFTP Java协议应用
程序员文章站
2022-04-15 19:31:22
· FTP服务器搭建 本文使用Win10搭建的SFTP服务器,关于Win10下SFTP服务器的搭建,搭建可以参考本博的另一篇博文《Win10 基于FreeSSHd搭建SFTP服务 配置详解》。 · Maven 依赖 com.jcraft jsch 0.1.55
· FTP服务器搭建
本文使用Win10搭建的SFTP服务器,关于Win10下SFTP服务器的搭建,搭建可以参考本博的另一篇博文《Win10 基于FreeSSHd搭建SFTP服务 配置详解》。
· Maven 依赖
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
· SFTP 工具类
package com.arhorchin.securitit.protocol.sftp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Properties;
import java.util.Vector;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
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;
import com.jcraft.jsch.SftpException;
/**
* @author Securitit.
* @note SFTP协议连接共享文件夹.
*/
public class SftpUtil {
/**
* logger.
*/
private Logger logger = Logger.getLogger(SftpUtil.class);
/**
* sftp.
*/
private ChannelSftp sftp;
/**
* session.
*/
private Session session;
/**
* SFTP 登录用户名.
*/
private String username;
/**
* SFTP 登录密码.
*/
private String pp;
/**
* 私钥.
*/
private String privateKey;
/**
* SFTP 服务器地址IP地址.
*/
private String host;
/**
* SFTP 端口.
*/
private int port;
/**
* 构造基于密码认证的sftp对象.
* @param username .
* @param pp .
* @param host .
* @param port .
*/
public SftpUtil(String username, String pp, String host, int port) {
this.username = username;
this.pp = pp;
this.host = host;
this.port = port;
}
/**
* 构造基于秘钥认证的sftp对象.
* @param username .
* @param host .
* @param port .
* @param privateKey .
*/
public SftpUtil(String username, String host, int port, String privateKey) {
this.username = username;
this.host = host;
this.port = port;
this.privateKey = privateKey;
}
/**
* 连接sftp服务器.
*/
public void sftpLogin() throws Exception {
JSch jsch = null;
Properties config = null;
Channel channel = null;
try {
JSch.setLogger(new SftpLogger());
jsch = new JSch();
// 设置私钥.
if (privateKey != null) {
jsch.addIdentity(privateKey);
}
session = jsch.getSession(username, host, port);
// 设置密码.
if (pp != null) {
session.setPassword(pp);
}
config = new Properties();
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications", "password");
session.setConfig(config);
session.connect(10000);
channel = session.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
} catch (JSchException ex) {
logger.error(ex);
throw new Exception(ex);
}
}
/**
* 关闭连接 server.
*/
public void sftpLogout() {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
}
}
if (session != null) {
if (session.isConnected()) {
session.disconnect();
}
}
}
/**
* 上传文件.
* @param sftpBasepath 基础目录.
* @param sftpFilename 文件名称.
* @param fileBytes 文件内容.
* @throws SftpException .
* @return 上传结果.
*/
public boolean sftpUpload(String sftpBasepath, String sftpFilename, byte[] fileBytes) throws Exception {
ByteArrayInputStream sftpFileBais = null;
try {
sftp.cd(sftp.getHome());
if (!StringUtils.isEmpty(sftpBasepath)) {
sftpMkdir(sftpBasepath);
}
sftpFileBais = new ByteArrayInputStream(fileBytes);
sftp.put(sftpFileBais, sftpFilename);
return true;
} catch (SftpException ex) {
logger.error(ex);
return false;
}
}
/**
* 下载文件.
* @param sftpBasepath 基础目录.
* @param sftpFilename 文件名称.
* @throws SftpException .
* @throws FileNotFoundException.
* @return 下载文件.
*/
public byte[] download(String sftpBasepath, String sftpFilename) throws Exception {
ByteArrayOutputStream sftpFileBaos = null;
try {
sftp.cd(sftp.getHome());
if (!StringUtils.isEmpty(sftpBasepath)) {
sftpMkdir(sftpBasepath);
}
sftpFileBaos = new ByteArrayOutputStream();
sftp.get(sftpFilename, sftpFileBaos);
return sftpFileBaos.toByteArray();
} catch (Exception ex) {
logger.error(ex);
return null;
}
}
/**
* 删除文件.
* @param sftpBasepath 基础目录.
* @param sftpFilename 文件名称.
* @throws SftpException.
* @return 删除结果.
*/
public boolean delete(String sftpBasepath, String sftpFilename) throws Exception {
try {
sftp.cd(sftp.getHome());
if (!StringUtils.isEmpty(sftpBasepath)) {
sftpMkdir(sftpBasepath);
}
sftp.rm(sftpFilename);
return true;
} catch (Exception ex) {
logger.error(ex);
return false;
}
}
/**
* 列出目录下的文件.
* @param sftpDirectory 目录.
* @return 目录内容.
* @throws SftpException .
*/
public Vector<?> sftpListFiles(String sftpDirectory) throws Exception {
return sftp.ls(sftpDirectory);
}
/**
* 创建多层目录.
* @param sftpPath .
* @throws Exception .
*/
public void sftpMkdir(String sftpPath) throws Exception {
try {
sftp.cd(sftpPath);
} catch (SftpException e) {
String[] dirs = sftpPath.split("/");
String tempPath = sftp.getHome();
for (String dir : dirs) {
if (null == dir || "".equals(dir))
continue;
tempPath += "/" + dir;
try {
sftp.cd(tempPath);
} catch (SftpException ex) {
sftp.mkdir(tempPath);
sftp.cd(tempPath);
}
}
}
}
}
· 测试类如下:
package com.arhorchin.securitit.protocol.sftp;
import java.io.File;
import org.apache.commons.io.FileUtils;
/**
* @author Securitit.
* @note SftpUtil测试.
*/
public class SftpUtilTester {
public static void main(String[] args) throws Exception {
String sftpIp = "192.168.120.1";
Integer sftpPort = 22;
String sftpUsername = "sftp";
String sftpPassword = "123456";
SftpUtil sftp = null;
// 登录SFTP服务器.
sftp = new SftpUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
sftp.sftpLogin();
// 上传文件.
byte[] fileBytes = FileUtils.readFileToByteArray(new File("C:/Users/Administrator/Downloads/个人文件/test.pdf"));
sftp.sftpUpload("/Test", "test.pdf", fileBytes);
// 下载文件.
fileBytes = sftp.sftpDownload("/Test", "test.pdf");
System.out.println("下载文件大小:" + fileBytes.length);
// 删除文件.
sftp.sftpDelete("/Test", "test.pdf");
// 退出SFTP登录.
sftp.sftpLogout();
}
}
· 总结
· 监控服务器SFTP物理路径可以看到文件的变化。
· 测试类输出内容中,可以看到下载的文件长度,说明下载成功了。
· SftpUtil工具类可以拿来直接使用,本人已进行过简单测试。
· com.jcraft.jsch.JSchException: Auth fail 如果发生Auth fail,则需要检查自己的配置,按照如下配置检查:
① 首先确认FreeSSHd以管理员方式启动
② 对FreeSSHd用户进行重新设置:重新启动FreeSSHd进程,使用删除+新增操作代替修改用户操作,删除用户,然后新增用户并设置认证方式和权限等信息,最后启动服务。
本文地址:https://blog.csdn.net/securitit/article/details/107590372
上一篇: vue项目 双层循环第二层获取不到第一层的下标如何解决
下一篇: PHP如何实现HTTP验证