feature:定制化ftp服务

release
gaorl 2 years ago
parent b3c02d2e34
commit 2d07a8ce64
  1. 2
      dxhy-core/pom.xml
  2. 2
      dxhy-customs/pom.xml
  3. 2
      dxhy-erp/pom.xml
  4. 1
      dxhy-oss/README
  5. 132
      dxhy-oss/pom.xml
  6. 154
      dxhy-oss/src/main/java/com/dxhy/oss/config/OssConfig.java
  7. 23
      dxhy-oss/src/main/java/com/dxhy/oss/config/OssReturnConfig.java
  8. 19
      dxhy-oss/src/main/java/com/dxhy/oss/model/FileModel.java
  9. 41
      dxhy-oss/src/main/java/com/dxhy/oss/service/AliOssService.java
  10. 72
      dxhy-oss/src/main/java/com/dxhy/oss/service/FileService.java
  11. 353
      dxhy-oss/src/main/java/com/dxhy/oss/service/FtpService.java
  12. 46
      dxhy-oss/src/main/java/com/dxhy/oss/service/JdOssService.java
  13. 186
      dxhy-oss/src/main/java/com/dxhy/oss/service/impl/AliOssServiceImpl.java
  14. 195
      dxhy-oss/src/main/java/com/dxhy/oss/service/impl/FileServiceImpl.java
  15. 213
      dxhy-oss/src/main/java/com/dxhy/oss/service/impl/JdOssServiceImpl.java
  16. 55
      dxhy-oss/src/main/java/com/dxhy/oss/service/impl/OssClientFactory.java
  17. 60
      dxhy-oss/src/main/java/com/dxhy/oss/utils/FileTypeUtils.java
  18. 31
      dxhy-oss/src/main/java/com/dxhy/oss/utils/SftpConfig.java
  19. 96
      dxhy-oss/src/main/java/com/dxhy/oss/utils/SftpFactory.java
  20. 41
      dxhy-oss/src/main/java/com/dxhy/oss/utils/SftpPool.java
  21. 15
      dxhy-oss/src/main/java/com/dxhy/oss/utils/SftpPoolException.java
  22. 61
      dxhy-oss/src/main/java/com/dxhy/oss/utils/SftpProperties.java
  23. 13
      dxhy-oss/src/test/java/com/dxhy/DxhyOssApplication.java
  24. 40
      dxhy-oss/src/test/java/com/dxhy/OfdHandle.java
  25. 127
      dxhy-oss/src/test/java/com/dxhy/OssTest.java
  26. 43
      dxhy-oss/src/test/java/com/dxhy/SpringContextUtils.java
  27. 48
      dxhy-oss/src/test/resources/application.yml
  28. 2
      dxhy-portrait/pom.xml
  29. 2
      dxhy-sign/pom.xml
  30. 1
      pom.xml

@ -150,7 +150,7 @@
<dependency>
<groupId>com.dxhy.jxpt</groupId>
<artifactId>dxhy-oss</artifactId>
<version>3.2.9</version>
<version>3.3.3</version>
</dependency>
<!-- itext pdf相关 -->
<dependency>

@ -111,7 +111,7 @@
<dependency>
<groupId>com.dxhy.jxpt</groupId>
<artifactId>dxhy-oss</artifactId>
<version>3.2.9</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>

@ -107,7 +107,7 @@
<dependency>
<groupId>com.dxhy.jxpt</groupId>
<artifactId>dxhy-oss</artifactId>
<version>3.2.9</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>

@ -0,0 +1 @@
README

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
<parent>
<groupId>com.dxhy</groupId>
<artifactId>ofd</artifactId>
<version>3.2.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.dxhy.jxpt</groupId>
<artifactId>dxhy-oss</artifactId>
<version>3.3.3</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.13.2</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.131</version>
</dependency>
<!-- ftp -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<!-- 使用commons-pool2 实现ftp连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.7.0</version>
</dependency>
<!-- minio 存储依赖 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>releases</id>
<name>releases</name>
<url>http://10.1.20.6:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>snapshots</name>
<url>http://10.1.20.6:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>大象慧云</id>
<name>Public Repositories</name>
<url>http://10.1.20.6:8081/nexus/content/groups/public/</url>
</repository>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,154 @@
package com.dxhy.oss.config;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.jcraft.jsch.ChannelSftp;
import lombok.Data;
/**
* @author jiaohongyang
*/
@Component
@Data
public class OssConfig {
/**
* oss 服务类型 JD AL FTP
*/
@Value("${oss.ossType:FTP}")
public String ossType;
/**
* 阿里请求地址
*/
@Value("${oss.endpointUrl:}")
public String endpointUrl;
/**
* 访问密钥
*/
@Value("${oss.accessKeyId:}")
public String accessKeyId;
/**
* 访问密钥
*/
@Value("${oss.accessKeySecret:}")
public String accessKeySecret;
/**
* 京东云地域
*/
@Value("${oss.region:}")
public String region;
/**
* 实例
*/
@Value("${oss.bucketName:}")
public String bucketName;
/**
* ftp上传的根路径
*/
@Value("${ftp.connection.pathPrefix:}")
public String pathPrefix;
/**
* ftp服务器地址
*/
@Value("${ftp.connection.hostname:}")
public String hostname;
/**
* ftp服务器端口
*/
@Value("${ftp.connection.port:62236}")
public String port;
/**
* ftp登录密码
*/
@Value("${ftp.connection.password:}")
public String password;
@Value("${ftp.connection.timeout:6000}")
public String timeout;
/**
* ftp登录账号
*/
@Value("${ftp.connection.username:}")
public String username;
@Value("${ftp.connection.localPathDefault:}")
public String localPathDefault;
/**
* 临时路径
*/
@Value("${ftp.connection.tempPath:}")
public String tempPath;
/**
* ftp配置信息
*/
@Value("${ftp.connection.size:2}")
public String pdfSize;
/**
* 图片的最大大小
*/
@Value("${oss.imageSize:10485760}")
public long imageSize;
/**
* 其他文件的最大大小
*/
@Value("${oss.fileSize:1073741824}")
public long fileSize;
private Pool pool = new Pool();
public static class Pool extends GenericObjectPoolConfig<ChannelSftp> {
private int maxTotal = DEFAULT_MAX_TOTAL;
private int maxIdle = DEFAULT_MAX_IDLE;
private int minIdle = DEFAULT_MIN_IDLE;
public Pool() {
super();
}
@Override
public int getMaxTotal() {
return maxTotal;
}
@Override
public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}
@Override
public int getMaxIdle() {
return maxIdle;
}
@Override
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
@Override
public int getMinIdle() {
return minIdle;
}
@Override
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
}
}

@ -0,0 +1,23 @@
package com.dxhy.oss.config;
/**
* @author jiaohongyang焦红阳
* @date 2020-09-30
*/
public interface OssReturnConfig {
String SUCCESS = "000000";
String ERROR_01 = "000001";
String ERROR_09 = "999999";
String JD = "JD";
String AL = "AL";
String FTP = "FTP";
String TOS = "TOS";
String MINIO = "MINIO";
}

@ -0,0 +1,19 @@
package com.dxhy.oss.model;
import lombok.Data;
/**
* @author jiaohongyang焦红阳
* @date 2020-10-17
*/
@Data
public class FileModel {
/**
* 编码
*/
private String code;
/**
* 文件地址
*/
private String filePath;
}

@ -0,0 +1,41 @@
package com.dxhy.oss.service;
import com.dxhy.oss.model.FileModel;
/**
* @author jiaohongyang
*/
public interface AliOssService {
/**
* 阿里云OSS文件存储
*
* @param file 文件
* @return 返回
*/
FileModel uploadFile(String fileName, String file);
/**
* 下载
*
* @param fileName 文件名称
* @param filePath 本地文件存储地址
* @return 返回
*/
FileModel downloadFile(String fileName, String filePath);
/**
* 删除文件
*
* @param file 文件名
* @return 返回
*/
FileModel deleteFile(String file);
/**
* 生产文件下载地址
*
* @param key 文件传输路径加名称
* @return 返回下载地址
*/
FileModel getUrl(String key);
}

@ -0,0 +1,72 @@
package com.dxhy.oss.service;
import com.dxhy.oss.model.FileModel;
/**
* @author jiaohongyang
*/
public interface FileService {
/**
* 文件上传
*
* @param fileName 文件 ftp名称
* @param originFileName 本地文件地址
* @return 返回
* @throws Exception 异常
*/
FileModel uploadFile(String fileName, String originFileName) throws Exception;
/**
* 文件下载
*
* @param downloadFile 下载文件
* @param saveFile 保存文件地址
* @return 返回
* @throws Exception 异常
*/
FileModel downFile(String downloadFile, String saveFile) throws Exception;
/**
* 生成文件下载地址
*
* @param key 文件传输路径加名称
* @return 返回文件下载地址
*/
FileModel getUrl(String key);
/**
* 删除文件
*
* @param file 文件地址
* @return 返回
*/
FileModel deleteFile(String file);
/**
* 获取ftp 上传地址
*
* @return 返回
*/
String getPathPrefix();
/**
* 图片本地地址
*
* @return 返回
*/
String getLocalPathDefault();
/**
* 临时路径
*/
String getTempPath();
/**
* PDF 上传文件大小
*/
String getFtpPdfSize();
}

@ -0,0 +1,353 @@
package com.dxhy.oss.service;
import cn.hutool.core.io.FileUtil;
import com.dxhy.oss.utils.SftpPool;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
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 java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* @author jiaohongyang
*/
@Slf4j
public class FtpService {
private final SftpPool pool;
public FtpService(SftpPool pool) {
this.pool = pool;
}
/**
* 将输入流的数据上传到sftp作为文件文件完整路径 = basePath+directory
*
* @param pathName ftp服务保存地址完整路径
* @param fileName 上传到ftp的文件名
* @param originFileName 待上传文件的名称绝对地址
*/
public boolean uploadFile(String pathName, String fileName, String originFileName) throws InterruptedException {
log.info("开始上传文件");
ChannelSftp sftp = null;
InputStream inputStream;
try {
sftp = pool.borrowObject();
try {
sftp.cd(pathName);
} catch (SftpException e) {
// 目录不存在,则创建文件夹
String[] dirs = pathName.split("/");
String tempPath = "";
for (String dir : dirs) {
if (null == dir || "".equals(dir)) {
continue;
}
tempPath += "/" + dir;
try {
sftp.cd(tempPath);
} catch (SftpException ex) {
try {
sftp.mkdir(tempPath);
sftp.cd(tempPath);
} catch (SftpException e1) {
e1.printStackTrace();
}
}
}
}
File orgFile = new File(originFileName);
inputStream = Files.newInputStream(orgFile.toPath());
sftp.put(inputStream, fileName);
inputStream.close();
// 删除本地文件,防止服务器空间不足
FileUtil.del(orgFile);
log.info("上传文件成功");
return true;
} catch (Exception e) {
e.printStackTrace();
log.info("上传文件失败");
return false;
} finally {
if (sftp != null) {
log.info("回收线程");
pool.returnObject(sftp);
}
}
}
public static boolean uploadFile(FTPClient ftpClient, String serviceDec, String fileName, InputStream inputStream) {
try {
log.info("开始上传文件");
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
createDirecroty(ftpClient, serviceDec);
ftpClient.makeDirectory(serviceDec);
ftpClient.changeWorkingDirectory(serviceDec);
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
log.info("上传文件成功");
} catch (Exception e) {
log.error("上传文件失败" + e);
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
if (null != inputStream) {
inputStream.close();
}
} catch (IOException e) {
log.error("上传文件失败" + e);
return false;
}
}
return true;
}
private static boolean createDirecroty(FTPClient ftpClient, String remote) throws IOException {
boolean success = true;
String directory = remote + "/";
// 如果远程目录不存在,则递归创建远程服务器目录
if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(ftpClient, new String(directory))) {
int start = 0;
int end = 0;
if (directory.startsWith("/")) {
start = 1;
} else {
start = 0;
}
end = directory.indexOf("/", start);
String path = "";
String paths = "";
while (true) {
String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
path = path + "/" + subDirectory;
if (!existFile(ftpClient, path)) {
if (makeDirectory(ftpClient, subDirectory)) {
changeWorkingDirectory(ftpClient, subDirectory);
} else {
log.info("创建目录[" + subDirectory + "]失败");
changeWorkingDirectory(ftpClient, subDirectory);
}
} else {
changeWorkingDirectory(ftpClient, subDirectory);
}
paths = paths + "/" + subDirectory;
start = end + 1;
end = directory.indexOf("/", start);
// 检查所有目录是否创建完毕
if (end <= start) {
break;
}
}
}
return success;
}
//改变目录路径
private static boolean changeWorkingDirectory(FTPClient ftpClient, String directory) {
boolean flag = true;
try {
flag = ftpClient.changeWorkingDirectory(directory);
if (flag) {
log.info("进入文件夹" + directory + " 成功!");
} else {
log.info("进入文件夹" + directory + " 失败!开始创建文件夹");
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return flag;
}
//判断ftp服务器文件是否存在
private static boolean existFile(FTPClient ftpClient, String path) throws IOException {
boolean flag = false;
FTPFile[] ftpFileArr = ftpClient.listFiles(path);
if (ftpFileArr.length > 0) {
flag = true;
}
return flag;
}
//创建目录
private static boolean makeDirectory(FTPClient ftpClient, String dir) {
boolean flag = true;
try {
flag = ftpClient.makeDirectory(dir);
if (flag) {
log.info("创建文件夹" + dir + " 成功!");
} else {
log.info("创建文件夹" + dir + " 失败!");
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 获取FTP某一特定目录下的所有文件名称
*
* @param ftpClient 已经登陆成功的FTPClient
* @param ftpDirPath FTP上的目标文件路径
*/
public static List getFileNameList(FTPClient ftpClient, String ftpDirPath) {
List list = new ArrayList();
try {
if (ftpDirPath.startsWith("/") && ftpDirPath.endsWith("/")) {
// 通过提供的文件路径获取FTPFile对象列表
FTPFile[] files = ftpClient.listFiles(ftpDirPath);
// 遍历文件列表,打印出文件名称
for (int i = 0; i < files.length; i++) {
FTPFile ftpFile = files[i];
// 此处只打印文件,未遍历子目录(如果需要遍历,加上递归逻辑即可)
if (ftpFile.isFile()) {
// log.info(ftpDirPath + ftpFile.getName());
list.add(ftpFile.getName());
}
}
log.info("当前FTP路径可用");
} else {
log.info("当前FTP路径不可用");
}
} catch (IOException e) {
log.error("错误" + e);
}
return list;
}
public File downloadFile(FTPClient ftpClient, String servicePath, String fileName, String localFilePath) {
String name = dowFile(ftpClient, servicePath, fileName, localFilePath);
if (name != null && !name.equals("")){
return new File(fileName);
}
return null;
}
private static String dowFile(FTPClient ftpClient, String servicePath, String fileName, String localFilePath) {
InputStream is = null;
FileOutputStream fos = null;
try {
ftpClient.enterLocalPassiveMode();
is = ftpClient.retrieveFileStream(servicePath + fileName);// 获取ftp上的文件
fos = new FileOutputStream(new File(localFilePath + fileName));
// 文件读取方式一
int i;
byte[] bytes = new byte[1024];
while ((i = is.read(bytes)) != -1) {
fos.write(bytes, 0, i);
}
// 文件读取方式二
//ftpClient.retrieveFile(ftpFilePath, new FileOutputStream(new File(localFilePath)));
ftpClient.completePendingCommand();
log.info("FTP文件下载成功!");
} catch (Exception e) {
log.error("FTP文件下载失败!" + e);
} finally {
try {
if (fos != null) fos.close();
if (is != null) is.close();
} catch (IOException e) {
log.error("下载流关闭失败" + e);
return null;
}
}
return localFilePath + fileName;
}
public boolean downloadFile(String directory, String downloadFile, String saveFile) {
log.info("开始下载文件!");
ChannelSftp sftp = null;
try {
sftp = pool.borrowObject();
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
}
String file = saveFile + "/" + downloadFile;
File fileLocal = new File(file);
if (fileLocal.exists()) {
boolean delete = fileLocal.delete();
log.info("删除本地路径文件:{}", delete);
}
this.directoryIsExists(saveFile);
sftp.get(downloadFile, file);
log.info("下载文件成功!");
return true;
} catch (Exception e) {
e.printStackTrace();
log.info("下载文件失败!");
return false;
} finally {
if (sftp != null) {
log.info("回收线程");
pool.returnObject(sftp);
}
}
}
/**
* 删除文件
*
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
* @return 返回是否删除成功
*/
public boolean deleteFile(String directory, String deleteFile) {
ChannelSftp sftp = null;
try {
sftp = pool.borrowObject();
sftp.cd(directory);
sftp.rm(deleteFile);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (sftp != null) {
log.info("回收线程");
pool.returnObject(sftp);
}
}
}
public void directoryIsExists(String path) {
File directory = new File(path);
if (directory.exists()) {
return;
}
if (!directory.mkdir()) {
return;
}
if (directory.canWrite()) {
return;
}
boolean setWritable = directory.setWritable(true);
log.info("是否创建文件 directoryIsExists :{} ", setWritable);
}
}

@ -0,0 +1,46 @@
package com.dxhy.oss.service;
import com.dxhy.oss.model.FileModel;
/**
* @author jiaohongyang
*/
public interface JdOssService {
/**
* 阿里云OSS文件存储
*
* @param file
* 文件
* @return 返回
*/
FileModel uploadFile(String fileName, String file);
/**
* 下载
*
* @param fileName
* 文件名称
* @param filePath
* 本地文件存储地址
* @return 返回
*/
FileModel downloadFile(String fileName, String filePath);
/**
* 生成文件下载地址
*
* @param key
* 文件传输路径加名称
* @return 返回文件下载地址
*/
FileModel getUrl(String key);
/**
* 删除文件
*
* @param file
* 文件信息
* @return 返回
*/
FileModel deleteFile(String file);
}

@ -0,0 +1,186 @@
package com.dxhy.oss.service.impl;
import cn.hutool.core.io.FileUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.GetObjectRequest;
import com.dxhy.oss.config.OssConfig;
import com.dxhy.oss.config.OssReturnConfig;
import com.dxhy.oss.model.FileModel;
import com.dxhy.oss.service.AliOssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.net.URL;
import java.util.Date;
/**
* @author jiaohongyang
*/
@Service("aliOssService")
@Slf4j
public class AliOssServiceImpl implements AliOssService {
private final OssConfig ossConfig;
@Autowired
public AliOssServiceImpl(OssConfig ossConfig) {
this.ossConfig = ossConfig;
}
/**
* 阿里云OSS文件存储
*
* @param filePath 文件
* @return 返回
*/
@Override
public FileModel uploadFile(String fileName, String filePath) {
OSS ossClient = null;
FileModel fileModel;
log.info("文件存储阿里OSS,存储目录:{} , 存储文件名:{} ", ossConfig.getBucketName(), fileName);
try {
// 创建连接
ossClient =
OssClientFactory.getInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
if (ossClient == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
// 进行文件上传
ossClient.putObject(ossConfig.getBucketName(), fileName, new File(filePath));
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
fileModel.setFilePath(fileName);
return fileModel;
} catch (Exception e) {
log.error("文件存储阿里OSS失败,异常:{}", e.getMessage());
e.printStackTrace();
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
FileUtil.del(filePath);
}
}
@Override
public FileModel getUrl(String key) {
OSS ossClient = null;
FileModel fileModel;
try {
ossClient =
OssClientFactory.getInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
if (ossClient == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
// 设置URL过期时间为10年 3600l* 1000*24*365*10
Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24);
// 生成URL
URL url = ossClient.generatePresignedUrl(ossConfig.getBucketName(), key, expiration);
if (url != null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
fileModel.setFilePath(url.toString());
return fileModel;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
/**
* 下载
*
* @param fileName 文件名称
* @param filePath 本地文件存储地址
* @return 返回
*/
@Override
public FileModel downloadFile(String fileName, String filePath) {
log.info("下载文件阿里OSS,存储目录:{} , 存储文件名:{} ", ossConfig.getBucketName(), fileName);
OSS ossClient = null;
FileModel fileModel;
try {
// 创建连接
ossClient =
OssClientFactory.getInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
if (ossClient == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
ossClient.getObject(new GetObjectRequest(ossConfig.getBucketName(), fileName), new File(filePath));
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
fileModel.setFilePath(filePath);
return fileModel;
} catch (Exception e) {
log.error("文件下载阿里OSS失败,异常:{}", e.getMessage());
e.printStackTrace();
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
/**
* 删除文件
*
* @param file 文件名
* @return 返回
*/
@Override
public FileModel deleteFile(String file) {
log.info("文件删除阿里OSS,存储目录:{} , 存储文件名:{} ", ossConfig.getBucketName(), file);
OSS ossClient = null;
FileModel fileModel;
try {
// 创建连接
ossClient =
OssClientFactory.getInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
if (ossClient == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
ossClient.deleteObject(ossConfig.getBucketName(), file);
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
return fileModel;
} catch (Exception e) {
log.error("文件删除阿里OSS失败,异常:{}", e.getMessage());
e.printStackTrace();
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}

@ -0,0 +1,195 @@
package com.dxhy.oss.service.impl;
import cn.hutool.core.io.FileUtil;
import com.dxhy.oss.config.OssConfig;
import com.dxhy.oss.config.OssReturnConfig;
import com.dxhy.oss.model.FileModel;
import com.dxhy.oss.service.AliOssService;
import com.dxhy.oss.service.FileService;
import com.dxhy.oss.service.FtpService;
import com.dxhy.oss.service.JdOssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
/**
* @author jiaohongyang
*/
@Slf4j
@Service("fileService")
public class FileServiceImpl implements FileService {
private final OssConfig ossConfig;
private final AliOssService aliOssService;
private final JdOssService jdOssService;
private final FtpService ftpService;
@Autowired
public FileServiceImpl(OssConfig ossConfig, AliOssService aliOssService, JdOssService jdOssService, FtpService ftpService) {
this.ossConfig = ossConfig;
this.aliOssService = aliOssService;
this.jdOssService = jdOssService;
this.ftpService = ftpService;
}
/**
* 文件上传
*
* @param fileName 上传文件路径+ 名称
* @param originFileName 本地文件地址
* @return 返回
* @throws Exception 异常
*/
@Override
public FileModel uploadFile(String fileName, String originFileName) throws Exception {
log.info("上传文件地址:{} , 本地存储文件地址:{}", fileName, originFileName);
FileModel fileModel;
if (OssReturnConfig.AL.equals(ossConfig.getOssType())) {
if (fileName.startsWith("/")) {
fileName = fileName.substring(1);
}
fileModel = aliOssService.uploadFile(fileName, originFileName);
} else if (OssReturnConfig.JD.equals(ossConfig.getOssType())) {
if (fileName.startsWith("/")) {
fileName = fileName.substring(1);
}
fileModel = jdOssService.uploadFile(fileName, originFileName);
} else if (OssReturnConfig.FTP.equals(ossConfig.getOssType())) {
if (!fileName.startsWith("/")) {
fileName = "/" + fileName;
}
String directory = fileName.substring(0, fileName.lastIndexOf("/"));
File directoryFile = new File(fileName);
String downloadFileName = directoryFile.getName();
boolean b = ftpService.uploadFile(directory, downloadFileName, originFileName);
fileModel = new FileModel();
fileModel.setFilePath(fileName);
if (b) {
fileModel.setCode(OssReturnConfig.SUCCESS);
} else {
fileModel.setCode(OssReturnConfig.ERROR_09);
}
} else {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
}
log.info("文件上传结果编码:{},地址信息返回:{}", fileModel.getCode(), fileModel.getFilePath());
return fileModel;
}
@Override
public FileModel downFile(String downloadFile, String saveFile) {
log.info("下载文件地址:{} , 本地存储文件地址:{}", downloadFile, saveFile);
// 获取下载文件存储路径 ,路径不存在则创建路径
File file = new File(saveFile);
String path = file.getParent();
FileUtil.mkdir(path);
FileModel fileModel;
if (OssReturnConfig.AL.equals(ossConfig.getOssType())) {
if (downloadFile.startsWith("/")) {
downloadFile = downloadFile.substring(1);
}
fileModel = aliOssService.downloadFile(downloadFile, saveFile);
} else if (OssReturnConfig.JD.equals(ossConfig.getOssType())) {
if (downloadFile.startsWith("/")) {
downloadFile = downloadFile.substring(1);
}
fileModel = jdOssService.downloadFile(downloadFile, saveFile);
} else if (OssReturnConfig.FTP.equals(ossConfig.getOssType())) {
String directory = downloadFile.substring(0, downloadFile.lastIndexOf("/"));
File directoryFile = new File(downloadFile);
String downloadFileName = directoryFile.getName();
boolean b = ftpService.downloadFile(directory, downloadFileName, path);
fileModel = new FileModel();
fileModel.setFilePath(saveFile);
if (b) {
fileModel.setCode(OssReturnConfig.SUCCESS);
} else {
fileModel.setCode(OssReturnConfig.ERROR_09);
}
} else {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
}
log.info("文件下载结果编码:{},地址信息返回:{}", fileModel.getCode(), fileModel.getFilePath());
return fileModel;
}
@Override
public FileModel getUrl(String key) {
FileModel fileModel;
log.info("生成文件下载地址:{} ", key);
if (OssReturnConfig.AL.equals(ossConfig.getOssType())) {
fileModel = aliOssService.getUrl(key);
} else if (OssReturnConfig.JD.equals(ossConfig.getOssType())) {
fileModel = jdOssService.getUrl(key);
} else {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
}
log.info("生成文件下载地址结果编码:{},地址链接返回:{}", fileModel.getCode(), fileModel.getFilePath());
return fileModel;
}
@Override
public FileModel deleteFile(String path) {
log.info("删除文件信息:{} ", path);
FileModel fileModel;
if (OssReturnConfig.AL.equals(ossConfig.getOssType())) {
if (path.startsWith("/")) {
path = path.substring(1);
}
fileModel = aliOssService.deleteFile(path);
} else if (OssReturnConfig.JD.equals(ossConfig.getOssType())) {
if (path.startsWith("/")) {
path = path.substring(1);
}
fileModel = jdOssService.deleteFile(path);
} else if (OssReturnConfig.FTP.equals(ossConfig.getOssType())) {
File file = new File(path);
boolean b = ftpService.deleteFile(file.getParent(), file.getName());
if (b) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
} else {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_01);
}
} else {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
}
log.info("删除文件信息返回结果编码:{}", fileModel.getCode());
return fileModel;
}
@Override
public String getPathPrefix() {
return ossConfig.getPathPrefix();
}
@Override
public String getLocalPathDefault() {
return ossConfig.getLocalPathDefault();
}
@Override
public String getTempPath() {
return ossConfig.getTempPath();
}
/**
* PDF 上传文件大小
*/
@Override
public String getFtpPdfSize() {
return ossConfig.getPdfSize();
}
}

@ -0,0 +1,213 @@
package com.dxhy.oss.service.impl;
import cn.hutool.core.io.FileUtil;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import com.dxhy.oss.config.OssConfig;
import com.dxhy.oss.config.OssReturnConfig;
import com.dxhy.oss.model.FileModel;
import com.dxhy.oss.service.JdOssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
/**
* @author jiaohongyang
*/
@Service("jdOssService")
@Slf4j
public class JdOssServiceImpl implements JdOssService {
private final OssConfig ossConfig;
@Autowired
public JdOssServiceImpl(OssConfig ossConfig) {
this.ossConfig = ossConfig;
}
/**
* 京东云OSS文件存储
*
* @param filePath 文件
* @return 返回
*/
@Override
public FileModel uploadFile(String fileName, String filePath) {
FileModel fileModel;
AmazonS3 jdInstance = null;
log.info("文件存储京东OSS,存储目录:{} , 存储文件名:{} ", ossConfig.getBucketName(), fileName);
try {
// 创建连接
jdInstance = OssClientFactory.getJdInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(),
ossConfig.getAccessKeySecret(), ossConfig.getRegion());
if (jdInstance == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
// 进行文件上传
jdInstance.putObject(ossConfig.getBucketName(), fileName, new File(filePath));
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
fileModel.setFilePath(fileName);
return fileModel;
} catch (Exception e) {
log.error("文件存储京东OSS失败,异常:{}", e.getMessage());
e.printStackTrace();
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
} finally {
if (jdInstance != null) {
jdInstance.shutdown();
}
FileUtil.del(filePath);
}
}
/**
* 下载
*
* @param fileName 文件名称
* @param filePath 本地文件存储地址
* @return 返回
*/
@Override
public FileModel downloadFile(String fileName, String filePath) {
log.info("下载文件京东OSS,存储目录:{} , 存储文件名:{} ", ossConfig.getBucketName(), fileName);
AmazonS3 jdInstance = null;
S3ObjectInputStream s3is = null;
FileOutputStream fos = null;
FileModel fileModel;
try {
// 创建连接
jdInstance = OssClientFactory.getJdInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(),
ossConfig.getAccessKeySecret(), ossConfig.getRegion());
if (jdInstance == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
S3Object object = jdInstance.getObject(ossConfig.getBucketName(), fileName);
s3is = object.getObjectContent();
fos = new FileOutputStream(filePath);
byte[] readBuf = new byte[1024];
int readLen = 0;
while ((readLen = s3is.read(readBuf)) > 0) {
fos.write(readBuf, 0, readLen);
}
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
fileModel.setFilePath(filePath);
return fileModel;
} catch (Exception e) {
e.printStackTrace();
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
} finally {
try {
if (s3is != null) {
s3is.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (jdInstance != null) {
jdInstance.shutdown();
}
}
}
@Override
public FileModel getUrl(String key) {
log.info("生成文件下载地址京东OSS,存储目录:{} , 存储文件名:{} ", ossConfig.getBucketName(), key);
AmazonS3 jdInstance = null;
FileModel fileModel;
try {
// 创建连接
jdInstance = OssClientFactory.getJdInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(),
ossConfig.getAccessKeySecret(), ossConfig.getRegion());
if (jdInstance == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
// 设置URL过期时间为10年 3600l* 1000*24*365*10
Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 2);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(ossConfig.getBucketName(), key);
request.setExpiration(expiration);
URL url = jdInstance.generatePresignedUrl(request);
if (url != null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
fileModel.setFilePath(url.toString());
return fileModel;
}
} catch (Exception e) {
e.printStackTrace();
log.error("文件下载京东OSS失败,异常:{}", e.getMessage());
} finally {
if (jdInstance != null) {
jdInstance.shutdown();
}
}
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
/**
* 删除文件
*
* @param file 文件名
* @return 返回
*/
@Override
public FileModel deleteFile(String file) {
log.info("文件删除京东云OSS,存储目录:{} , 存储文件名:{} ", ossConfig.getBucketName(), file);
AmazonS3 jdInstance = null;
FileModel fileModel;
try {
// 创建连接
// 创建连接
jdInstance = OssClientFactory.getJdInstance(ossConfig.getEndpointUrl(), ossConfig.getAccessKeyId(),
ossConfig.getAccessKeySecret(), ossConfig.getRegion());
if (jdInstance == null) {
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
}
jdInstance.deleteObject(ossConfig.getBucketName(), file);
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.SUCCESS);
return fileModel;
} catch (Exception e) {
log.error("文件删除京东云OSS失败,异常:{}", e.getMessage());
e.printStackTrace();
fileModel = new FileModel();
fileModel.setCode(OssReturnConfig.ERROR_09);
return fileModel;
} finally {
if (jdInstance != null) {
jdInstance.shutdown();
}
}
}
}

@ -0,0 +1,55 @@
package com.dxhy.oss.service.impl;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
/**
* @author jiaohongyang
*/
@Slf4j
public class OssClientFactory {
private OssClientFactory() {
}
/**
* 创建连接
*/
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static OSS getInstance(String endpointUrl, String accessKeyId, String accessKeySecret) {
return new OSSClientBuilder().build(endpointUrl, accessKeyId, accessKeySecret);
}
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static AmazonS3 getJdInstance(String endpointUrl, String accessKeyId, String accessKeySecret,
String region) {
ClientConfiguration config = new ClientConfiguration();
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(endpointUrl, region);
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKeyId, accessKeySecret);
AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
return AmazonS3Client.builder().withEndpointConfiguration(endpointConfig).withClientConfiguration(config)
.withCredentials(awsCredentialsProvider).disableChunkedEncoding().withPathStyleAccessEnabled(true)
.build();
}
}

@ -0,0 +1,60 @@
package com.dxhy.oss.utils;
import cn.hutool.core.io.FileTypeUtil;
import java.io.InputStream;
/**
* 文件类型工具类
* TODO 其中只是定义了部分文件格式有缺失的自己添加
*/
public class FileTypeUtils {
private final static String IMAGE_TYPE = "image/";
private final static String AUDIO_TYPE = "audio/";
private final static String VIDEO_TYPE = "video/";
private final static String APPLICATION_TYPE = "application/";
private final static String TXT_TYPE = "text/";
public static String getFileType(InputStream fileInputStream) {
String type = null;
try {
type = FileTypeUtil.getType(fileInputStream);
if (type.equalsIgnoreCase("JPG") || type.equalsIgnoreCase("JPEG")
|| type.equalsIgnoreCase("GIF") || type.equalsIgnoreCase("PNG")
|| type.equalsIgnoreCase("BMP") || type.equalsIgnoreCase("PCX")
|| type.equalsIgnoreCase("TGA") || type.equalsIgnoreCase("PSD")
|| type.equalsIgnoreCase("TIFF")) {
return IMAGE_TYPE + type;
}
if (type.equalsIgnoreCase("mp3") || type.equalsIgnoreCase("OGG")
|| type.equalsIgnoreCase("WAV") || type.equalsIgnoreCase("REAL")
|| type.equalsIgnoreCase("APE") || type.equalsIgnoreCase("MODULE")
|| type.equalsIgnoreCase("MIDI") || type.equalsIgnoreCase("VQF")
|| type.equalsIgnoreCase("CD")) {
return AUDIO_TYPE + type;
}
if (type.equalsIgnoreCase("mp4") || type.equalsIgnoreCase("avi")
|| type.equalsIgnoreCase("MPEG-1") || type.equalsIgnoreCase("RM")
|| type.equalsIgnoreCase("ASF") || type.equalsIgnoreCase("WMV")
|| type.equalsIgnoreCase("qlv") || type.equalsIgnoreCase("MPEG-2")
|| type.equalsIgnoreCase("MPEG4") || type.equalsIgnoreCase("mov")
|| type.equalsIgnoreCase("3gp")) {
return VIDEO_TYPE + type;
}
if (type.equalsIgnoreCase("doc") || type.equalsIgnoreCase("docx")
|| type.equalsIgnoreCase("ppt") || type.equalsIgnoreCase("pptx")
|| type.equalsIgnoreCase("xls") || type.equalsIgnoreCase("xlsx")
|| type.equalsIgnoreCase("zip") || type.equalsIgnoreCase("jar")) {
return APPLICATION_TYPE + type;
}
if (type.equalsIgnoreCase("txt")) {
return TXT_TYPE + type;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

@ -0,0 +1,31 @@
package com.dxhy.oss.utils;
import com.dxhy.oss.service.FtpService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// ftp配置
@Configuration
@EnableConfigurationProperties(SftpProperties.class)
public class SftpConfig {
// 工厂
@Bean
public SftpFactory sftpFactory(SftpProperties properties) {
return new SftpFactory(properties);
}
// 连接池
@Bean
public SftpPool sftpPool(SftpFactory sftpFactory) {
return new SftpPool(sftpFactory);
}
// 辅助类
@Bean
public FtpService ftpService(SftpPool sftpPool) {
return new FtpService(sftpPool);
}
}

@ -0,0 +1,96 @@
package com.dxhy.oss.utils;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import java.util.Properties;
@EqualsAndHashCode(callSuper = true)
@Data
@Slf4j
public class SftpFactory extends BasePooledObjectFactory<ChannelSftp> {
private SftpProperties ossConfig;
public SftpFactory(SftpProperties ossConfig) {
this.ossConfig = ossConfig;
}
@Override
public ChannelSftp create() throws SftpPoolException {
try {
JSch jsch = new JSch();
Session session = jsch.getSession(ossConfig.getUsername(), ossConfig.getHostname(), Integer.parseInt(ossConfig.getPort()));
// 设置密码
if (ossConfig.getPassword() != null) {
session.setPassword(ossConfig.getPassword());
}
// 设置密码
if (ossConfig.getPassword() != null) {
session.setPassword(ossConfig.getPassword());
}
// 为Session对象设置properties
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// 设置超时时间
session.setTimeout(Integer.parseInt(ossConfig.getTimeout()));
// 建立链接
session.connect();
// 打开SFTP通道
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
// 建立SFTP通道的连接
channel.connect();
return channel;
} catch (JSchException e) {
throw new SftpPoolException("获取ftp连接失败", e);
}
}
public FTPClient createFtp() throws SftpPoolException{
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8");// 中文支持
ftpClient.setConnectTimeout(1000 * 30);//设置连接超时时间
ftpClient.connect(ossConfig.getHostname(), Integer.valueOf(ossConfig.getPort()));// 连接FTP服务器
ftpClient.login(ossConfig.getUsername(), ossConfig.getPassword());// 登陆FTP服务器
// 设置文件类型为二进制(如果从FTP下载或上传的文件是压缩文件的时候,不进行该设置可能会导致获取的压缩文件解压失败)
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// ftpClient.enterLocalPassiveMode();//开启被动模式,否则文件上传不成功,也不报错
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
log.info("连接FTP失败,用户名或密码错误。");
ftpClient.disconnect();
} else {
log.info("FTP连接成功!");
}
} catch (Exception e) {
log.info("登陆FTP失败,请检查FTP相关配置信息是否正确!" + e);
return null;
}
return ftpClient;
}
@Override
public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) {
return new DefaultPooledObject<>(channelSftp);
}
// 销毁对象
@Override
public void destroyObject(PooledObject<ChannelSftp> p) {
ChannelSftp channelSftp = p.getObject();
channelSftp.disconnect();
}
}

@ -0,0 +1,41 @@
package com.dxhy.oss.utils;
import com.jcraft.jsch.ChannelSftp;
import lombok.Data;
import org.apache.commons.pool2.impl.GenericObjectPool;
@Data
public class SftpPool {
private GenericObjectPool<ChannelSftp> pool;
public SftpPool(SftpFactory factory) {
this.pool = new GenericObjectPool<>(factory, factory.getOssConfig().getPool());
}
/**
* 获取一个sftp连接对象
*
* @return sftp连接对象
*/
public ChannelSftp borrowObject() throws SftpPoolException {
try {
return pool.borrowObject();
} catch (Exception e) {
e.printStackTrace();
throw new SftpPoolException("获取ftp连接失败", e);
}
}
/**
* 归还一个sftp连接对象
*
* @param channelSftp sftp连接对象
*/
public void returnObject(ChannelSftp channelSftp) {
if (channelSftp != null) {
pool.returnObject(channelSftp);
}
}
}

@ -0,0 +1,15 @@
package com.dxhy.oss.utils;
/**
* @author jiaohongyang
* @date 2019年3月26日 下午5:57:26
*/
public class SftpPoolException extends Exception {
public SftpPoolException(String message, Exception e) {
super(message, e);
}
}

@ -0,0 +1,61 @@
package com.dxhy.oss.utils;
import com.jcraft.jsch.ChannelSftp;
import lombok.Data;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "ftp.connection")
public class SftpProperties {
private String hostname;
private String port = "22";
private String username;
private String password;
private String timeout;
private Pool pool = new Pool();
public static class Pool extends GenericObjectPoolConfig<ChannelSftp> {
private int maxTotal = DEFAULT_MAX_TOTAL;
private int maxIdle = DEFAULT_MAX_IDLE;
private int minIdle = DEFAULT_MIN_IDLE;
public Pool() {
super();
}
@Override
public int getMaxTotal() {
return maxTotal;
}
@Override
public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}
@Override
public int getMaxIdle() {
return maxIdle;
}
@Override
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
@Override
public int getMinIdle() {
return minIdle;
}
@Override
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
}
}

@ -0,0 +1,13 @@
package com.dxhy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.dxhy.*")
public class DxhyOssApplication {
public static void main(String[] args) {
SpringApplication.run(DxhyOssApplication.class, args);
}
}

@ -0,0 +1,40 @@
package com.dxhy;
import com.dxhy.oss.model.FileModel;
import com.dxhy.oss.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
/**
* @author user
*/
@SuppressWarnings("FieldCanBeLocal")
@Slf4j
public class OfdHandle extends Thread {
private final File file;
@Autowired
private FileService fileService;
public OfdHandle(File file) {
this.file = file;
}
@Override
public void run() {
fileService = (FileService) SpringContextUtils.getBean("fileService");
FileModel fileModel = new FileModel();
try {
fileModel = fileService.uploadFile(file.getPath(), file.getPath());
} catch (Exception e) {
e.printStackTrace();
}
log.info("文件上传返回结果:" + fileModel.getCode() + " " + fileModel.getFilePath());
}
}

@ -0,0 +1,127 @@
package com.dxhy;
import java.io.File;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.dxhy.oss.model.FileModel;
import com.dxhy.oss.service.FileService;
import cn.hutool.core.io.FileUtil;
/**
* @author jiaohongyang焦红阳
* @date 2020-09-30
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DxhyOssApplication.class)
public class OssTest {
@Resource
private FileService fileService;
@Test
public void ossUploadTest() {
String fileName = "/GYL/YONGHUI/2022/09/08/update.zip";
String originFileName = "/Users/jiaohongyang/product/project/project/jxpt/ofd/pdf/update.zip";
FileModel fileModel = new FileModel();
try {
fileModel = fileService.uploadFile(fileName, originFileName);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("文件上传返回结果:" + fileModel.getCode() + " " + fileModel.getFilePath());
}
@Test
public void ossGylUploadTest() {
String fileName = "/GYL/DUODIAN/2022/12/07/update.zip";
String originFileName = "/Users/jiaohongyang/product/project/project/jxpt/ofd/pdf/update.zip";
FileModel fileModel = new FileModel();
try {
fileModel = fileService.uploadFile(fileName, originFileName);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("文件上传返回结果:" + fileModel.getCode() + " " + fileModel.getFilePath());
}
@Test
public void ossGylSdlpUploadTest() {
String fileName = "/GYL/SDLP/2022/09/20/51发票助手_local_J_1.4.8.exe";
String originFileName = "/Users/jiaohongyang/product/project/project/jxpt/ofd/pdf/51发票助手_local_J_1.4.8.exe";
FileModel fileModel = new FileModel();
try {
fileModel = fileService.uploadFile(fileName, originFileName);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("文件上传返回结果:" + fileModel.getCode() + " " + fileModel.getFilePath());
}
@Test
public void ossDownloadTest() {
String downloadFile = "/jxfp/pdf/2022/1111/dxhy-admin.jar";
// String downloadFile = "/jxfp/excel/2020/10/12/1282510566564315137_进项票据采集_2020-10-12_1602489969696.xlsx";
String saveFile = "/Users/jiaohongyang/product/project/project/jxpt/ofd/pdf/dxhy-admin.jar";
FileModel fileModel = new FileModel();
try {
fileModel = fileService.downFile(downloadFile, saveFile);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("文件下载返回结果" + fileModel.getCode() + " " + fileModel.getFilePath());
}
@Test
public void ossgetUrlTest() {
String key = "/GYL/SDLP/2022/09/14/供应链协同开票助手-v1.1.0.1.20220914-x86_Setup.zip";
FileModel fileModel = fileService.getUrl(key);
System.out.println(fileModel.getCode() + " " + fileModel.getFilePath());
}
@Test
public void ossDeleteTest() {
String downloadFile = "GYL/DUODIAN/2022/12/01/20221201(1.1.0.2).zip";
FileModel fileModel = new FileModel();
try {
fileModel = fileService.deleteFile(downloadFile);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("文件删除返回结果" + fileModel.getCode());
}
@Test
public void ossPush() {
String path = "/Volumes/product/PDF/";
try {
File[] ls = FileUtil.ls(path);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2000, 10000, 60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(ls.length), r -> new Thread(r, "oss推送-" + r.hashCode()));
for (File file : ls) {
if (!threadPoolExecutor.isShutdown()) {
threadPoolExecutor.execute(new OfdHandle(file));
}
}
threadPoolExecutor.shutdown();
threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,43 @@
package com.dxhy;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring Context 工具类
*
* @author jiaohongyang
*/
@Component
public class SpringContextUtils implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<?> getType(String name) {
return applicationContext.getType(name);
}
}

@ -0,0 +1,48 @@
#oss:
# ossType: AL
# endpointUrl: http://oss-accelerate.aliyuncs.com
# accessKeyId: LTAI4G6XxTTwUzcY3ByWa6Yb
# accessKeySecret: kkgPJ4DIvkOcvfZPl4BE1FVqyQlPiq
# region:
# bucketName: jiaohongyang
#oss:
# ossType: JD
# endpointUrl: https://storage.jd.local
# accessKeyId: bfac05320eaf11cc80cf1823e4fb87d98523fc94
# accessKeySecret: 70ec454ffb302043a7837417e0909e12d1288d0b
# region: cn-north-1
# bucketName: input-tax-invoice
#oss:
# ossType: AL
# endpointUrl: http://oss-cn-beijing-internal.aliyuncs.com
# accessKeyId: LTAI4GHGCEiWsXxTZ651wV22
# accessKeySecret: hTXim31f5JmIMz3rcj7WIopKAUscsE
# region:
# bucketName: guowangtest
#oss:
# ossType: MINIO
# endpointUrl: http://10.1.2.107:9000
# accessKeyId: minioadmin
# accessKeySecret: minioadmin
# region:
# bucketName: jxpt
oss:
ossType: JD
endpointUrl: https://s3.cn-north-1.jdcloud-oss.com
accessKeyId: 4B2A089EA1C8F776357A15948DBCA363
accessKeySecret: 570296481BA33BFC4A8C9EEB5E00652A
region: cn-north-1
bucketName: jxdownload
ftp:
connection:
hostname: 10.1.2.87
username: dxhy1
password: dxhy
port: 62236
timeout: 60000
pathPrefix: /jxfp/excel/
# 连接池参数
pool:
max-total: 10
max-idle: 10
min-idle: 5

@ -106,7 +106,7 @@
<dependency>
<groupId>com.dxhy.jxpt</groupId>
<artifactId>dxhy-oss</artifactId>
<version>3.2.9</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>

@ -118,7 +118,7 @@
<dependency>
<groupId>com.dxhy.jxpt</groupId>
<artifactId>dxhy-oss</artifactId>
<version>3.2.9</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>

@ -21,6 +21,7 @@
<module>dxhy-admin</module>
<module>dxhy-gateway</module>
<module>dxhy-base</module>
<module>dxhy-oss</module>
<module>dxhy-core</module>
<module>dxhy-erp</module>
<module>dxhy-extend</module>

Loading…
Cancel
Save