springBoot整合sftp
1.引入依赖,pom文件添加依赖。
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
2.在application.yml文件添加sftp配置。
sftp:
protocol: sftp #协议
host: 127.0.0.1 # ip
port: 22 # 端口
username: alex
password: ******
3.编写SftpProperties。
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "sftp")
public class SftpProperties {
private String protocol;
private String host;
private Integer port;
private String username;
private String password;
}
4.编写SftpUtils。
import com.jcraft.jsch.*;
import com.yeyoo.sftp.config.SftpProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class SftpUtils {
@Autowired
private SftpProperties config;
/**
* 创建SFTP连接
* @return
* @throws Exception
*/
public ChannelSftp createSftp() throws Exception {
JSch jsch = new JSch();
log.info("Try to connect sftp[" + config.getUsername() + "@" + config.getHost() + "], use password[" + config.getPassword() + "]");
Session session = createSession(jsch, config.getHost(), config.getUsername(), config.getPort());
session.setPassword(config.getPassword());
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
log.info("Session connected to {}.", config.getHost());
Channel channel = session.openChannel(config.getProtocol());
channel.connect();
log.info("Channel created to {}.", config.getHost());
return (ChannelSftp) channel;
}
/**
* 创建session
* @param jsch
* @param host
* @param username
* @param port
* @return
* @throws Exception
*/
public Session createSession(JSch jsch, String host, String username, Integer port) throws Exception {
Session session = null;
if (port <= 0) {
session = jsch.getSession(username, host);
} else {
session = jsch.getSession(username, host, port);
}
if (session == null) {
throw new Exception(host + " session is null");
}
return session;
}
/**
* 关闭连接
* @param sftp
*/
public void disconnect(ChannelSftp sftp) {
try {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
} else if (sftp.isClosed()) {
log.info("sftp is closed already");
}
if (null != sftp.getSession()) {
sftp.getSession().disconnect();
}
}
} catch (JSchException e) {
e.printStackTrace();
}
}
}
5.编写SftpFileService。
public interface SftpFileService {
boolean uploadFile(String sftpPath,String targetPath,String sftpFileName,String targetFileName) throws Exception;
boolean downloadFile(String sftpPath,String targetPath,String sftpFileName,String targetFileName) throws Exception;
}
6.编写SftpFileServiceImpl。
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpATTRS;
import com.yeyoo.sftp.service.SftpFileService;
import com.yeyoo.sftp.utils.SftpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Vector;
/**
* @description: SFTP文件服务实现类
* @author: wzg
* @create: 2021-09-17
**/
@Slf4j
@Service
public class SftpFileServiceImpl implements SftpFileService {
@Autowired
private SftpUtils sftpUtils;
/**
*
* @param sftpPath sftp文件目录
* @param targetPath 目标存放文件目录
* @param sftpFileName sftp文件名
* @param targetFileName 下载保存文件名
* @return
* @throws Exception
*/
@Override
public boolean downloadFile(String sftpPath, String targetPath,String sftpFileName,String targetFileName) throws Exception {
long start = System.currentTimeMillis();
// 开启sftp连接
ChannelSftp sftp = sftpUtils.createSftp();
OutputStream outputStream = null;
try {
boolean isExist = isDirExist(sftpPath,sftp);
// sftp文件夹存在
if(isExist){
// 进入sftp文件目录
sftp.cd(sftpPath);
log.info("Change path to {}", sftpPath);
File file = new File(targetPath+targetFileName);
// 如果文件已经存在,删除
if (file.exists()) {
file.delete();
}
// 创建文件夹
new File(targetPath).mkdirs();
// 创建文件
file.createNewFile();
outputStream = new FileOutputStream(file);
if(sftpFileName.equals("")){
Vector fileList = sftp.ls(sftpPath);
Iterator it = fileList.iterator();
while (it.hasNext()) {
ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) it.next();
sftpFileName = entry.getFilename();
}
}
// 下载文件
sftp.get(sftpFileName, outputStream);
log.info("{} Download file success. TargetPath: {},Total time {}ms.",targetFileName, targetPath,System.currentTimeMillis()-start);
return true;
}else{
log.info("sftp文件夹不存在");
return false;
}
} catch (Exception e) {
log.error("Download file failure. targetFileName: {}", targetFileName, e);
throw new Exception(targetFileName+" Download File failure");
} finally {
if (outputStream != null) {
outputStream.close();
}
// 关闭sftp
sftpUtils.disconnect(sftp);
}
}
/**
*
* @param sftpPath sftp文件目录
* @param localPath 本地存放文件目录
* @param sftpFileName sftp文件名
* @param localFileName 本地文件名
* @return
* @throws Exception
*/
@Override
public boolean uploadFile(String sftpPath, String localPath, String sftpFileName, String localFileName) throws Exception {
// 开启sftp连接
ChannelSftp sftp = sftpUtils.createSftp();
FileInputStream in = null;
try {
// 进入sftp文件目录
sftp.cd(sftpPath);
log.info("Change path to {}", sftpPath);
File localFile = new File(localPath+localFileName);
in = new FileInputStream(localFile);
// 上传文件
sftp.put(in, sftpFileName);
log.info("upload file success. TargetPath: {}", sftpPath);
return true;
} catch (Exception e) {
log.error("upload file failure. sftpPath: {}", sftpPath, e);
throw new Exception("upload File failure");
} finally {
if (in != null) {
in.close();
}
// 关闭sftp
sftpUtils.disconnect(sftp);
}
}
/**
* 判断目录是否存在
* @param directory
* @return
*/
public boolean isDirExist(String directory,ChannelSftp sftp)
{
boolean isDirExistFlag = false;
try
{
SftpATTRS sftpATTRS = sftp.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
}
catch (Exception e)
{
if (e.getMessage().toLowerCase().equals("no such file"))
{
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
}
7.编写SftpFileController进行测试。
import com.yeyoo.sftp.service.SftpFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/sftp")
public class SftpFileController {
@Autowired
private SftpFileService sftpFileService;
@RequestMapping("/downLoad")
public Map downLoad() throws Exception {
String sftpPath = "/update_data/20210909/";
String sftpFileName = "test.csv.gz";
String targetPath = "/data/tianyancha/";
String targetFileName = "company_wechat.csv.gz";
File file = sftpFileService.downloadFile(sftpPath,targetPath,sftpFileName,targetFileName);
Map map = new HashMap<>();
map.put("code",200);
map.put("message","success");
map.put("data",file);
return map;
}
}