/**
* 按照 edi配置循环sftp 服务器处理海关报文
*
* @param ediId edi配置的EDI ID
* @param ediConfigProperty edi配置信息
*/
public void scanSFtpFiles(String ediId, EdiConfigProperty ediConfigProperty) {
FtpConfigProperties ftpConfigProperties = ediConfigProperty.getFtp();
SftpUtils utils = SftpUtils.newInstance();
try {
ChannelSftp channel = utils.getChannel(ftpConfigProperties, 3000, 3);
if (Objects.isNull(channel)) {
log.error("通道建立失败,无法处理EDI目录文件");
return;
}
List<String> fileNames = utils.listDir(ftpConfigProperties.getBasedir());
for (String fileName : fileNames) {
try {
log.info("load file:{}", fileName);
String content = utils.readFile(fileName, ftpConfigProperties.getBasedir());
if (processEdiDoc(ediId, ediConfigProperty, content)) {
log.info("success process file {}", fileName);
} else {
log.info("failed process file {}", fileName);
}
log.info("del file:{}", fileName);
utils.delFileNow(ftpConfigProperties.getBasedir() + File.separator + fileName);
log.info("finish file:{}", fileName);
} catch (Throwable t) {
log.error("biz error", t);
}
}
} catch (JSchException e) {
log.error("sftp error", e);
throw new BizException(e);
} finally {
utils.closeChannel();
}
}
/**
* 使用ftp方式处理edi报文
* @param ediId
* @param ediConfigProperty
*/
public void scanFtpFiles(String ediId, EdiConfigProperty ediConfigProperty) {
FtpConfigProperties ftpConfigProperties = ediConfigProperty.getFtp();
FtpConfig ftpConfig = FtpConfig.create()
.setHost(ftpConfigProperties.getIp())
.setPort(ftpConfigProperties.getPort())
.setUser(ftpConfigProperties.getUsername())
.setPassword(ftpConfigProperties.getUserpwd())
.setSoTimeout(5000)
.setConnectionTimeout(10000)
.setCharset(StandardCharsets.UTF_8);
try (Ftp ftp = new Ftp(ftpConfig, FtpMode.Passive)) {
String pwd = ftp.pwd();
List<FTPFile> files = ftp.lsFiles(pwd, ftpFile -> ftpFile.isFile() && ftpFile.getName().contains("HFEEIR"));
for (FTPFile ftpFile : files) {
try {
String fileName = ftpFile.getName();
log.info(">>>>> scanFtpFiles fileName={}", fileName);
ByteArrayOutputStream buff = new ByteArrayOutputStream(4096);
ftp.download(pwd, ftpFile.getName(), buff);
String content = StringUtils.replaceEach(buff.toString("utf-8"), new String[]{"\n", "\r"}, new String[]{"",""});
if (processEdiDoc(ediId, ediConfigProperty, content)) {
log.info(">>>>> scanFtpFiles success process file {}", fileName);
} else {
log.info(">>>>> scanFtpFiles failed process file {}", fileName);
}
ftp.delFile(fileName);
log.info(">>>>> scanFtpFiles ftpfileName={}, exist={}", fileName, ftp.existFile(fileName));
} catch (Throwable t) {
log.error(">>>>> scanFtpFiles biz error", t);
}
}
} catch (Exception e) {
log.error(">>>>> scanFtpFiles ftperror ediId:{} ", ediId, e);
}
}
package com.nuzar.fcms.accept.util.ftp;
import com.jcraft.jsch.*;
import com.nuzar.cloud.common.exception.BizException;
import com.nuzar.cloud.common.utils.StringUtils;
import com.nuzar.fcms.accept.config.FtpConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Random;
import java.util.*;
@Slf4j
public class SftpUtils {
private Channel channel;
private Session session;
private ChannelSftp sftp;
public static SftpUtils newInstance() {
return new SftpUtils();
}
public ChannelSftp getChannel(String ftpHost, int port, String ftpUserName, String ftpPassword, int timeout) {
return getChannel(ftpHost, port, ftpUserName, ftpPassword, timeout, 3);
}
public ChannelSftp getChannel(FtpConfigProperties ftpConfig, int timeout, int times) throws JSchException {
return getChannel(ftpConfig.getIp(), ftpConfig.getPort(), ftpConfig.getUsername(), ftpConfig.getUserpwd(), timeout, times);
}
public ChannelSftp getChannel(String ftpHost, int port, String ftpUserName, String ftpPassword, int timeout, int times) {
int connectTimes = 0;
while (sftp == null && connectTimes < times) {
connectTimes++;
try {
sftp = getChannel(ftpHost, port, ftpUserName, ftpPassword, timeout, "no");
log.info("连接SFTP = >> 连接成功");
} catch (Exception e) {
try {
log.info("连接SFTP = >> 连接不成功,开始重连...");
Thread.sleep(100 * new Random().nextInt(100));
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
return sftp;
}
public ChannelSftp getChannel(String ftpHost, int port, String ftpUserName, String ftpPassword, int timeout, String strictHostKeyChecking) throws JSchException {
JSch jsch = new JSch();
session = jsch.getSession(ftpUserName, ftpHost, port);
if (ftpPassword != null) {
session.setPassword(ftpPassword);
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", strictHostKeyChecking);
session.setConfig(config);
session.setTimeout(timeout);
session.connect();
log.info("jsch Session connected.");
channel = session.openChannel("sftp");
channel.connect();
log.info("jsch Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName);
return (ChannelSftp) channel;
}
public void uploadFile(InputStream inputStream, String originName, String remoteDir) {
try {
sftp.cd("/");
isRemoteDirExist(remoteDir);
sftp.put(inputStream, originName);
log.info("SFTP =>> 文件 {} 上传完成", originName);
} catch (SftpException e) {
log.info("SFTP 文件上传失败 ,路径[" + remoteDir + "],文件名 [" + originName + "]", e.getMessage());
}
}
public InputStream getDownloadFileStream(String originName, String remoteDir) {
try {
sftp.cd(remoteDir);
log.info("SFTP =>> 文件 {} 下载", originName);
return sftp.get(originName);
} catch (SftpException e) {
log.info("SFTP 文件下载失败 ,路径[" + remoteDir + "],文件名 [" + originName + "]", e.getMessage());
throw new BizException(e);
}
}
public String readFile(String originName, String remoteDir) {
BufferedReader bufferedReader = null;
StringBuilder content = new StringBuilder("");
try {
sftp.cd(remoteDir);//进入指定目录操作
InputStream inputStream = sftp.get(originName);
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String tempString = null;
while ((tempString = bufferedReader.readLine()) != null) {
content.append(tempString);
}
return content.toString();
} catch (Exception e) {
log.info("SFTP 文件读取失败 ,路径[" + remoteDir + "],文件名 [" + originName + "]", e.getMessage());
throw new BizException(e);
} finally {
try {
if (bufferedReader != null)
bufferedReader.close();//关闭流
} catch (IOException e) {
log.error("Close BufferedReader error:", e);
}
}
}
public void isRemoteDirExist(String remoteDir) {
try {
sftp.cd(remoteDir);
} catch (SftpException e) {
try {
String[] dirs = remoteDir.split("/");
for (String dir : dirs) {
if (StringUtils.isEmpty(dir)) {
continue;
}
try {
sftp.cd(dir);
} catch (SftpException e1) {
log.info("上传SFTP =>> 目录[" + dir + "]不存在,开始创建");
sftp.mkdir(dir);
log.info("上传SFTP =>> 目录[" + dir + "],目录创建成功,进入目录");
sftp.cd(dir);
}
}
} catch (SftpException ex) {
log.info("上传SFTP失败:{}", e.getMessage());
}
}
}
public void renameFile(String oldpath, String newpath) {
try {
sftp.rename(oldpath, newpath);
log.info("SFTP =>> 文件 {} 重命名完成", newpath);
} catch (SftpException e) {
log.info("SFTP 文件重命名失败 ,oldpath [" + oldpath + "],newpath [" + newpath + "]", e.getMessage());
}
}
public void delFileNow(String filePath) {
try {
if (isDir(filePath)) {
sftp.cd(filePath);
Vector<ChannelSftp.LsEntry> entries = sftp.ls(filePath);
for (ChannelSftp.LsEntry entry : entries) {
if (entry.getFilename().equals(".") || entry.getFilename().equals("..")) {
continue;
}
delFile(filePath + "/" + entry.getFilename());
}
} else {
sftp.rm(filePath);
}
} catch (SftpException e) {
e.printStackTrace();
log.info("SFTP 删除文件 [" + filePath + "]失败", e.getMessage());
}
}
public void delFile(String filePath) {
try {
if (isDir(filePath)) {
sftp.cd(filePath);
Vector<ChannelSftp.LsEntry> entries = sftp.ls(filePath);
for (ChannelSftp.LsEntry entry : entries) {
if (entry.getFilename().equals(".") || entry.getFilename().equals("..")) {
continue;
}
delFile(filePath + "/" + entry.getFilename());
}
} else {
SftpATTRS sftpATTRS = sftp.lstat(filePath);
Date date = new Date((long) sftpATTRS.getMTime() * 1000L);
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
LocalDateTime dateTime = LocalDateTime.now().plusDays(-7);
if (dateTime.isAfter(localDateTime)) {
log.info("SFTP 文件清理 =>> 删除7天前的文件[" + filePath + "]");
sftp.rm(filePath);
}
}
} catch (SftpException e) {
e.printStackTrace();
log.info("SFTP 删除文件 [" + filePath + "]失败", e.getMessage());
}
}
public boolean isDir(String filePath) {
try {
return sftp.stat(filePath).isDir();
} catch (SftpException e) {
e.printStackTrace();
}
return false;
}
public List<String> listDir(String filePath) {
List<String> fileNames = Lists.newArrayList();
try {
Vector<ChannelSftp.LsEntry> ls = sftp.ls(filePath);
for (ChannelSftp.LsEntry l : ls) {
//移除上级目录和根目录:"." ".."
if (".".equals(l.getFilename()) || "..".equals(l.getFilename()) || l.getFilename().startsWith(".")) {
continue;
}
String filename = l.getFilename();
fileNames.add(filename);
}
} catch (SftpException e) {
log.error("ls directory fail", e);
}
return fileNames;
}
public void closeChannel() {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
log.info("SFTP =>> 连接关闭");
}
public static void main(String[] args) {
SftpUtils channel = SftpUtils.newInstance();
ChannelSftp sftp = channel.getChannel("192.168.20.36", 22, "root", "Gx#P@ssw0rd", 1000);
if (sftp == null) {
return;
}
try {
//InputStream inputStream = new FileInputStream(new File("D:\\migration-tool-package.zip"));
//channel.uploadFile(inputStream,"migration-tool-package.zip","/home/aaaaa/bbbb");
//channel.renameFile("/home/aaaa/bbbbb/test.csv.tmp", "/home/aaaa/bbbbb/test.csv");
channel.delFile("/home/aaaa");
channel.closeChannel();
} catch (Exception e) {
e.printStackTrace();
}
}
}