|
|
@@ -1,16 +1,15 @@
|
|
|
package org.springblade.los.edi.service.impl;
|
|
|
|
|
|
-import cn.hutool.core.util.CharsetUtil;
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
|
+import com.jcraft.jsch.ChannelSftp;
|
|
|
+import com.jcraft.jsch.SftpException;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.apache.commons.net.ftp.FTP;
|
|
|
-import org.apache.commons.net.ftp.FTPClient;
|
|
|
-import org.apache.commons.net.ftp.FTPFile;
|
|
|
+import org.apache.commons.pool2.PooledObject;
|
|
|
import org.apache.commons.pool2.impl.GenericObjectPool;
|
|
|
import org.springblade.core.secure.utils.AuthUtil;
|
|
|
import org.springblade.los.Util.RegularUtils;
|
|
|
@@ -25,18 +24,14 @@ import org.springblade.los.business.sea.entity.ContainersCommodity;
|
|
|
import org.springblade.los.edi.dto.EdiAddress;
|
|
|
import org.springblade.los.edi.dto.InttraSoDto;
|
|
|
import org.springblade.los.edi.service.IEDISenderService;
|
|
|
-import org.springblade.los.ftp.service.FTPPoolService;
|
|
|
-import org.springblade.los.ftp.utils.ftp.FTPClientFactory;
|
|
|
+import org.springblade.los.ftp.utils.Sftp.ChannelSftpFactory;
|
|
|
+import org.springblade.los.ftp.utils.Sftp.SFtpConfig;
|
|
|
import org.springblade.los.ftp.utils.ftp.FTPPoolConfig;
|
|
|
-import org.springblade.los.ftp.utils.ftp.FTPUtil;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
-import java.io.BufferedWriter;
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileWriter;
|
|
|
-import java.io.IOException;
|
|
|
+import java.io.*;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
@@ -54,10 +49,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
|
|
|
private final IBLinesService bLinesService;
|
|
|
|
|
|
@Autowired
|
|
|
- private static FTPPoolConfig config;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- static FTPPoolService ftpPoolService;
|
|
|
+ static FTPPoolConfig config;
|
|
|
|
|
|
public static boolean createDir(String folder) {
|
|
|
if (!folder.endsWith(File.separator)) {
|
|
|
@@ -169,68 +161,92 @@ public class EDISenderServiceImpl implements IEDISenderService {
|
|
|
|
|
|
} else*/
|
|
|
if ("ftp".equals(item.getMode())) {
|
|
|
- config.setHost(item.getHost());
|
|
|
- config.setUsername(item.getUserName());
|
|
|
- config.setPassword(item.getPassword());
|
|
|
- config.setPort(Integer.parseInt(item.getAddress()));
|
|
|
- config.setWorkingDirectory(item.getPath());
|
|
|
+ SFtpConfig sFtpConfig = new SFtpConfig();
|
|
|
+ sFtpConfig.setWorkingDirectory(item.getPath());
|
|
|
+ sFtpConfig.setHost(item.getHost());
|
|
|
+ sFtpConfig.setPort(Integer.parseInt(item.getAddress()));
|
|
|
+ sFtpConfig.setUsername(item.getUserName());
|
|
|
+ sFtpConfig.setPassword(item.getPassword());
|
|
|
+ sFtpConfig.setEncoding("utf-8");
|
|
|
+ sFtpConfig.setClientTimeout(300000);
|
|
|
+ sFtpConfig.setRetryTimes(1200);
|
|
|
+ sFtpConfig.setBufferSize(8192);
|
|
|
+ sFtpConfig.setMaxTotal(50);
|
|
|
+ sFtpConfig.setMinldle(10);
|
|
|
+ sFtpConfig.setMaxldle(50);
|
|
|
+ sFtpConfig.setMaxWait(300000);
|
|
|
+ sFtpConfig.setBlockWhenExhausted(true);
|
|
|
+ sFtpConfig.setTestOnBorrow(true);
|
|
|
+ sFtpConfig.setTestOnReturn(true);
|
|
|
+ sFtpConfig.setTestOnCreate(true);
|
|
|
+ sFtpConfig.setTestWhileldle(false);
|
|
|
+ sFtpConfig.setLifo(false);
|
|
|
try {
|
|
|
- FTPClientFactory factory = new FTPClientFactory();
|
|
|
- factory.makeObject();
|
|
|
- GenericObjectPool<FTPClient> pool = new GenericObjectPool<FTPClient>(factory, config);
|
|
|
- FTPClient ftpClient = pool.borrowObject();
|
|
|
- ftpClient.changeWorkingDirectory(ftpPoolService.getFtpPoolConfig().getWorkingDirectory());
|
|
|
- // 设置PassiveMode传输
|
|
|
- ftpClient.enterLocalPassiveMode();
|
|
|
- // 设置以二进制流的方式传输
|
|
|
- ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
|
|
|
- ftpClient.setControlEncoding(CharsetUtil.UTF_8);
|
|
|
- FTPUtil ftpUtil = new FTPUtil();
|
|
|
- FTPUtil.UploadStatus result = FTPUtil.UploadStatus.UploadNewFileFailed;
|
|
|
- // 对远程目录的处理
|
|
|
- String remoteFileName = item.getPath();
|
|
|
- if (item.getPath().contains("/")) {
|
|
|
- remoteFileName = item.getPath().substring(item.getPath().lastIndexOf("/") + 1);
|
|
|
- // 创建服务器远程目录结构,创建失败直接返回
|
|
|
- if (ftpUtil.createDirecroty(item.getPath(), ftpClient) == FTPUtil.UploadStatus.CreateDirectoryFail) {
|
|
|
- message = "远程服务器相应目录创建失败";
|
|
|
- code = "500";
|
|
|
- }
|
|
|
+ //创建连接
|
|
|
+ ChannelSftpFactory factory = new ChannelSftpFactory();
|
|
|
+ //赋值连接配置数据
|
|
|
+ factory.setConfig(sFtpConfig);
|
|
|
+ //创建连接对象
|
|
|
+ ChannelSftp channelSftp = factory.createNew(sFtpConfig);
|
|
|
+ PooledObject<ChannelSftp> poola = factory.wrap(channelSftp);
|
|
|
+ if (!factory.validateObject(poola)){
|
|
|
+ throw new RuntimeException("无空闲连接通道,请稍后");
|
|
|
}
|
|
|
- // 检查远程是否存在文件
|
|
|
- FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes(CharsetUtil.UTF_8), CharsetUtil.ISO_8859_1));
|
|
|
- if (files.length == 1) {
|
|
|
- long remoteSize = files[0].getSize();
|
|
|
- long localSize = file.length();
|
|
|
- if (remoteSize == localSize) { // 文件存在
|
|
|
- message = "文件已经存在";
|
|
|
- code = "500";
|
|
|
- } else if (remoteSize > localSize) {
|
|
|
- message = "远程文件大于本地文件";
|
|
|
- code = "500";
|
|
|
- }
|
|
|
- // 尝试移动文件内读取指针,实现断点续传
|
|
|
- result = ftpUtil.uploadFile(remoteFileName, file, ftpClient, remoteSize);
|
|
|
- // 如果断点续传没有成功,则删除服务器上文件,重新上传
|
|
|
- if (result == FTPUtil.UploadStatus.UploadFromBreakFailed) {
|
|
|
- if (!ftpClient.deleteFile(remoteFileName)) {
|
|
|
- message = "断点续传失败";
|
|
|
- code = "500";
|
|
|
+ //创建Sftp连接池
|
|
|
+ GenericObjectPool<ChannelSftp> pool = new GenericObjectPool<>(factory, sFtpConfig);
|
|
|
+ //获取对象实例
|
|
|
+ ChannelSftp sftp = pool.borrowObject();
|
|
|
+ ChannelSftp sftp1 = null;
|
|
|
+ String filePath = item.getPath();
|
|
|
+ if (file.exists() && file.isFile()) {
|
|
|
+ //转换文件流
|
|
|
+ InputStream inputStream = new FileInputStream(file);
|
|
|
+ try {
|
|
|
+ sftp.cd(filePath);
|
|
|
+ String pwd = sftp.pwd();
|
|
|
+ //判断远程服务器是否存在文件夹
|
|
|
+ if (!(pwd.equals(filePath) || pwd.concat("/").equals(filePath))) {
|
|
|
+ int countFiles = 0;
|
|
|
+ try {
|
|
|
+ countFiles = sftp.ls(filePath).size();
|
|
|
+ } catch (SftpException e) {
|
|
|
+ mkdirs(sftp, filePath.split("/"), "", filePath.split("/").length, 0);
|
|
|
+ }
|
|
|
+ if (countFiles <= 1000) {
|
|
|
+ filePath = filePath;
|
|
|
+ } else {
|
|
|
+ String newPath = filePath + String.valueOf(System.currentTimeMillis()).substring(9);
|
|
|
+ mkdirs(sftp, newPath.split("/"), "", newPath.split("/").length, 0);
|
|
|
+ filePath = newPath;
|
|
|
+ }
|
|
|
}
|
|
|
- result = ftpUtil.uploadFile(remoteFileName, file, ftpClient, 0);
|
|
|
- if (result == FTPUtil.UploadStatus.UploadFromBreakSuccess) {
|
|
|
- message = "上传失败";
|
|
|
- code = "500";
|
|
|
+ filePath = filePath+"/";
|
|
|
+ //远程文件存放地址
|
|
|
+ filePath = filePath.concat(file.getName());
|
|
|
+ //判断是否sftp连接是否关闭
|
|
|
+ if (sftp.isClosed()) {
|
|
|
+ sftp.put(inputStream, filePath);
|
|
|
+ sftp.chmod(Integer.parseInt("755", 8), filePath);
|
|
|
+ } else {
|
|
|
+ sftp1 = pool.borrowObject();
|
|
|
+ sftp1.put(inputStream, filePath);
|
|
|
+ sftp1.chmod(Integer.parseInt("755", 8), filePath);
|
|
|
}
|
|
|
- }
|
|
|
- } else {
|
|
|
- result = ftpUtil.uploadFile(remoteFileName, file, ftpClient, 0);
|
|
|
- if (result != FTPUtil.UploadStatus.UploadFromBreakSuccess) {
|
|
|
- message = "上传失败";
|
|
|
- code = "500";
|
|
|
+ } catch (SftpException e) {
|
|
|
+ log.error("SFTP上传文件出错", e);
|
|
|
+ pool.returnObject(sftp);
|
|
|
+ factory.destroyObject(poola);
|
|
|
+ } finally {
|
|
|
+ if (sftp1 != null) {
|
|
|
+ pool.returnObject(sftp1);
|
|
|
+ }
|
|
|
+ pool.returnObject(sftp);
|
|
|
+ factory.destroyObject(poola);
|
|
|
+ inputStream.close();
|
|
|
}
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
+ log.error("SFTP上传文件出错", e);
|
|
|
throw new RuntimeException(e);
|
|
|
}
|
|
|
} /*else {
|
|
|
@@ -5003,5 +5019,30 @@ public class EDISenderServiceImpl implements IEDISenderService {
|
|
|
throw new SecurityException("生成edi文件失败");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ public static void mkdirs(ChannelSftp sftp, String[] dirs, String tempPath, int length, int index) {
|
|
|
+ // 以"/a/b/c/d"为例按"/"分隔后,第0位是"";顾下标从1开始
|
|
|
+ index++;
|
|
|
+ if (index < length) {
|
|
|
+ // 目录不存在,则创建文件夹
|
|
|
+ tempPath += "/" + dirs[index];
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ sftp.cd(tempPath);
|
|
|
+ if (index < length) {
|
|
|
+ mkdirs(sftp, dirs, tempPath, length, index);
|
|
|
+ }
|
|
|
+ } catch (SftpException ex) {
|
|
|
+ try {
|
|
|
+ sftp.mkdir(tempPath);
|
|
|
+ sftp.chmod(Integer.parseInt("755", 8), tempPath);
|
|
|
+ sftp.cd(tempPath);
|
|
|
+ } catch (SftpException e) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mkdirs(sftp, dirs, tempPath, length, index);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|