SFTP
简介
SFTP是Secure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的加密方法。SFTP 为 SSH的一部份,是一种传输文件到服务器的安全方式。SFTP是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。
使用介绍
JSch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到你自己的应用程序。
本文只介绍如何使用JSch实现的SFTP功能。
使用JSch需要添加下面的依赖包
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.51</version>
</dependency>
ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:
put(): 文件上传
get(): 文件下载
cd(): 进入指定目录
ls(): 得到指定目录下的文件列表
rename(): 重命名指定文件或目录
rm(): 删除指定文件
mkdir(): 创建目录
rmdir(): 删除目录
JSch支持三种文件传输模式:
OVERWRITE
完全覆盖模式,这是JSch的默认文件传输模式,即如果目标文件已经存在,传输的文件将完全覆盖目标文件,产生新的文件。
RESUME
恢复模式,如果文件已经传输一部分,这时由于网络或其他任何原因导致文件传输中断,如果下一次传输相同的文件,则会从上一次中断的地方续传。
APPEND
追加模式,如果目标文件已存在,传输的文件将在目标文件后追加。
文件上传例子:
常量类
package test.test;
/**
* 常量类
*
* @author duxiao
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class SFTPConstants {
public static final String SFTP_REQ_HOST = "host";
public static final String SFTP_REQ_PORT = "port";
public static final String SFTP_REQ_USERNAME = "username";
public static final String SFTP_REQ_PASSWORD = "password";
public static final int SFTP_DEFAULT_PORT = 22;
public static final String SFTP_REQ_LOC = "location";
}
创建ChannelSftp对象
package test.test;
import java.util.Map;
import java.util.Properties;
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;
/**
*
* SFTP通道对象<br>
* 在应用程序中就可以使用该对象来调用SFTP的各种操作方法。<br>
* 比如put(),get()等
*
* @author duxiao
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class SFTPChannel {
Session session = null;
Channel channel = null;
public ChannelSftp getChannel(Map<String, String> sftpDetails, int timeout) throws JSchException {
String ftpHost = sftpDetails.get(SFTPConstants.SFTP_REQ_HOST);
String port = sftpDetails.get(SFTPConstants.SFTP_REQ_PORT);
String ftpUserName = sftpDetails.get(SFTPConstants.SFTP_REQ_USERNAME);
String ftpPassword = sftpDetails.get(SFTPConstants.SFTP_REQ_PASSWORD);
int ftpPort = SFTPConstants.SFTP_DEFAULT_PORT;
if (port != null && !port.equals("")) {
ftpPort = Integer.valueOf(port);
}
// 创建JSch对象
JSch jsch = new JSch();
// 根据用户名,主机ip,端口获取一个Session对象
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
System.out.println("Session created.");
if (ftpPassword != null) {
// 设置密码
session.setPassword(ftpPassword);
}
Properties config = new Properties();
// 首次登陆远程的时候提示Are you sure you want to continue connecting (yes/no)。这时用sshpass会不好使。
config.put("StrictHostKeyChecking", "no");
// 为Session对象设置properties
session.setConfig(config);
// 设置timeout时间
session.setTimeout(timeout);
// 通过Session建立链接
session.connect();
System.out.println("Session connected.");
System.out.println("Opening Channel.");
// 打开SFTP通道
channel = session.openChannel("sftp");
// 建立SFTP通道的连接
channel.connect();
System.out.println("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName
+ ", returning: " + channel);
return (ChannelSftp) channel;
}
public void closeChannel() throws Exception {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
应用测试类
package test.test;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import com.jcraft.jsch.ChannelSftp;
/**
*
* 功能测试类
*
* @author duxiao
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class SFTPTest {
public SFTPChannel getSFTPChannel() {
return new SFTPChannel();
}
public static void main(String[] args) throws Exception {
SFTPTest test = new SFTPTest();
Map<String, String> sftpDetails = new HashMap<String, String>();
// 设置主机ip,端口,用户名,密码
sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, "172.16.128.165");
sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, "product");
sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, "U13QGqODA");
sftpDetails.put(SFTPConstants.SFTP_REQ_PORT, "22");
// 本地文件名
String src = "F:\\ueditor1_4_3-utf8-jsp.zip";
// 目标文件名
String dst = "/home/product/response/ueditor1_4_3-utf8-jsp.zip";
SFTPChannel channel = test.getSFTPChannel();
ChannelSftp chSftp = channel.getChannel(sftpDetails, 60000);
// 代码段1
// 使用OVERWRITE模式
OutputStream out = chSftp.put(dst, ChannelSftp.OVERWRITE);
// 设定每次传输的数据块大小为256KB
byte[] buff = new byte[1024 * 256];
int read;
if (out != null) {
System.out.println("Start to read input stream");
InputStream is = new FileInputStream(src);
do {
read = is.read(buff, 0, buff.length);
if (read > 0) {
out.write(buff, 0, read);
}
out.flush();
} while (read >= 0);
System.out.println("input stream read done.");
}
// 代码段2
// chSftp.put(src, dst, ChannelSftp.OVERWRITE);
// 代码段3
// chSftp.put(new FileInputStream(src), dst, ChannelSftp.OVERWRITE);
chSftp.quit();
channel.closeChannel();
}
}
其中测试类中的代码段1,2,3可以分别执行,体现了3中不同的上传方式,结果都是一致。
小伙伴们只要把这三个类考出去运行一下,java实现SFTP的各种功能就很容易理解了。
碰到问题
以前联通给我们消费记录需求需要该技术使用。后来需求改动。已经没有改技术的使用了。没有碰到问题。
评价
JSch是SSH2功能JAVA实现最常用的最好用的工具。
参考资料
百度文库的资料