java服务器常用文件传输协议_在Java中实现SFTP协议文件传输的两种解决方案

在Java中实现SFTP协议文件传输的两种解决方案

1.1 背景

1.2 关于 FTP /FTPS

1.3 关于SFTP

解决方案一:使用 JSch 库

解决方案二:使用sshj 库

这篇博文来聊聊在Java中实现SFTP协议文件传输的两种解决方案

1.1 背景

我们知道,XFTP 是一款非常流行的 FTP 文件传输工具。

其中 XFTP 目前支持两种文件传输协议

一种是FTP

9b952a6b1f9345e382f6246c8c306f6d.jpg

另外一种是SFTP

如图所示:

2efcc4fc553c4992bffaece5973bd43b.jpg

当然除此之外还有一种不太常用的FTPS

那么这三种协议有哪些区别呢?

文件传输协议类型

描述

FTP

基础的文件传输

FTPS

基于TLS 加密

SFTP

基于SSH 加密

有时候我们可能会有需求,在我们的项目中使用FTP 文件传输功能。

那么在Java中有哪些解决方案呢?

1.2 关于 FTP /FTPS

Apache Commons Net™库实现了许多基本Internet协议的客户端。

支持的协议如下所示:

FTP/FTPS

FTP over HTTP (experimental)

NNTP

SMTP(S)

POP3(S)

IMAP(S)

Telnet

TFTP

Finger

Whois

rexec/rcmd/rlogin

Time (rdate) and Daytime

Echo

Discard

NTP/SNTP

其中这个类库中有如下三个类:

org.apache.commons.net.tftp.TFTPClient

支持不需要账号密码访问的FTP 协议文件传输,不支持带验证的FTP文件传输

org.apache.commons.net.ftp.FTPClient

支持FTP,不支持FTPS和SFTP

org.apache.commons.net.ftp.FTPSClient

支持FTPS,不支持SFTP

前面两种方式这里不做过多讨论,我们重点看下SFTP 协议文件传输的解决方案。

1.3 关于SFTP

关于在Java中实现SFTP协议文件传输有两个库可供使用。

使用 JSch 库

使用sshj 库

为了便于测试,我这里将账号密码等信息配置成静态工具类

代码如下所示:

/**

* @author qing-feng.zhao

*/

public class MyServerInfoConstant {

/**

* FTP IP 地址

*

*/

public static final String REMOTE_SERVER_IP="127.0.0.1";

/**

* Sftp账号

*/

public static final String USER_NAME="root";

/**

* Sftp密码

*/

public static final String PASS_WORD="toor";

/**

* 测试远程服务器的文件路径

*/

public static final String SRC_FILE_PATH="/opt/app/remote.txt";

/**

* 本地保存文件路径

*/

public static final String TARGET_FILE_PATH="C:/test/local.txt";

/**

* 禁用构造方法

*/

private MyServerInfoConstant(){}

}

请自行修改IP 账号和密码为自己FTP 服务器的账号和密码。

解决方案一:使用 JSch 库

调用代码如下:

import com.xingyun.constant.MyServerInfoConstant;

import com.xingyun.utils.SmartSftpUtils;

/**

* http://www.jcraft.com/jsch/

* @author qing-feng.zhao

*/

public class SmartSftpUtilsTest {

public static void main(String[] args) {

//FTP IP

String remoteServerIp= MyServerInfoConstant.REMOTE_SERVER_IP;

//默认是22端口

//Sftp账号

String username=MyServerInfoConstant.USER_NAME;

//Sftp密码

String password=MyServerInfoConstant.PASS_WORD;

//远程服务器地址

String remoteFilePath=MyServerInfoConstant.SRC_FILE_PATH;

//本地保存文件路径

String localFilePath=MyServerInfoConstant.TARGET_FILE_PATH;

//调用工具类下载文件

SmartSftpUtils.downloadFileBySftp(remoteServerIp,username,password,remoteFilePath,localFilePath);

}

}

工具类配置如下:

import com.jcraft.jsch.*;

import lombok.extern.slf4j.Slf4j;

/**

* @sees http://www.jcraft.com/jsch/

* @author qing-fegn.zhao

*/

@Slf4j

public final class SmartSftpUtils {

/**

*

* @param remoteServerIp

* @param username

* @param password

* @param remoteFilePath

* @param localFilePath

*/

public static void downloadFileBySftp(String remoteServerIp,

String username,

String password,

String remoteFilePath,

String localFilePath){

JSch jsch = new JSch();

try {

Session session = jsch.getSession(username, remoteServerIp, 22);

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

session.setPassword(password);

session.connect();

Channel channel = session.openChannel("sftp");

channel.connect();

ChannelSftp sftpChannel = (ChannelSftp) channel;

sftpChannel.get(remoteFilePath, localFilePath);

sftpChannel.exit();

session.disconnect();

} catch (JSchException e) {

//To change body of catch statement use File | Settings | File Templates.

log.error(e.getMessage(),e);

} catch (SftpException e) {

log.error(e.getMessage(),e);

}

}

/**

* 禁用构造方法

*/

private SmartSftpUtils(){}

}

解决方案二:使用sshj 库

这个类库更加强大,除了基础的SFTP协议文件传输,还支持 Shell 下的各种常用命令,比如创建文件夹,列出文件目录等。

调用方法如下:

import com.xingyun.constant.MyServerInfoConstant;

import com.xingyun.utils.SmartSshUtils;

/**

* @author

*/

public class SmartSshUtilsTest {

public static void main(String[] args) {

String hostName= MyServerInfoConstant.REMOTE_SERVER_IP;

String username=MyServerInfoConstant.USER_NAME;

String password=MyServerInfoConstant.PASS_WORD;

String srcFilePath=MyServerInfoConstant.SRC_FILE_PATH;

String targetFilePath=MyServerInfoConstant.TARGET_FILE_PATH;

SmartSshUtils.downLoadFileBySsh(hostName,username,password,srcFilePath,targetFilePath);

}

}

sshJ工具类:

import lombok.extern.slf4j.Slf4j;

import net.schmizz.sshj.SSHClient;

import net.schmizz.sshj.sftp.SFTPClient;

import net.schmizz.sshj.transport.verification.PromiscuousVerifier;

import java.io.IOException;

/**

* https://github.com/hierynomus/sshj

* @Sees https://stackoverflow.com/questions/14617/how-to-retrieve-a-file-from-a-server-via-sftp

* @author qing-feng.zhao

*/

@Slf4j

public final class SmartSshUtils {

public static void downLoadFileBySsh(String hostName,

String username,

String password,

String srcFilePath,

String targetFilePath

) {

SSHClient ssh = new SSHClient();

SFTPClient sftpClient = null;

try {

//ssh.loadKnownHosts(); to skip host verification

ssh.addHostKeyVerifier(new PromiscuousVerifier());

ssh.connect(hostName);

ssh.authPassword(username, password);

sftpClient = ssh.newSFTPClient();

sftpClient.get(srcFilePath, targetFilePath);

//create a folder

sftpClient.mkdir("/opt/app/testFolder");

//sftpClient.mkdirs("");创建多级文件夹

//sftpClient.rmdir("");重命名文件夹

//sftpClient.ls(""); //列出当前目录

} catch (IOException e) {

log.error(e.getMessage(), e);

} finally {

if (null != sftpClient) {

try {

sftpClient.close();

} catch (IOException e) {

log.error(e.getMessage(), e);

}

}

try {

ssh.disconnect();

} catch (IOException e) {

log.error(e.getMessage(), e);

}

}

}

/**

* 静态工具类应该禁用构造方法

*/

private SmartSshUtils(){}

}

贴上完整的pom.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0modelVersion>

org.examplegroupId>

SmartFtpSampleartifactId>

1.0-SNAPSHOTversion>

UTF-8project.build.sourceEncoding>

1.8java.version>

${java.version}maven.compiler.source>

${java.version}maven.compiler.target>

3.5.1maven.compiler.plugin.version>

1.18.10lombok.version>

3.6commons.net.version>

2.1.6.RELEASEspring.boot.version>

0.1.55jsch.version>

0.27.0sshj.version>

properties>

org.projectlombokgroupId>

lombokartifactId>

${lombok.version}version>

providedscope>

dependency>

org.springframework.bootgroupId>

spring-boot-starter-loggingartifactId>

${spring.boot.version}version>

compilescope>

dependency>

commons-netgroupId>

commons-netartifactId>

${commons.net.version}version>

dependency>

com.jcraftgroupId>

jschartifactId>

${jsch.version}version>

dependency>

com.hierynomusgroupId>

sshjartifactId>

${sshj.version}version>

dependency>

dependencies>

org.apache.maven.pluginsgroupId>

maven-compiler-pluginartifactId>

${maven.compiler.plugin.version}version>

${java.version}source>

${java.version}target>

configuration>

plugin>

plugins>

build>

project>

这里只贴出部分,关于更多其他解决方案的探讨见我的Github.


版权声明:本文为weixin_35910782原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。