mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-23 07:41:53 +08:00
完善 yudao-spring-boot-starter-file 组件,支持 S3 对接云存储、local、ftp、sftp 等协议
This commit is contained in:
parent
ed53ca3de9
commit
3d40fc81dd
@ -22,13 +22,40 @@ public class FileUtils {
|
|||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static File createTempFile(String data) {
|
public static File createTempFile(String data) {
|
||||||
// 创建文件,通过 UUID 保证唯一
|
File file = createTempFile();
|
||||||
File file = File.createTempFile(IdUtil.simpleUUID(), null);
|
|
||||||
// 标记 JVM 退出时,自动删除
|
|
||||||
file.deleteOnExit();
|
|
||||||
// 写入内容
|
// 写入内容
|
||||||
FileUtil.writeUtf8String(data, file);
|
FileUtil.writeUtf8String(data, file);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建临时文件
|
||||||
|
* 该文件会在 JVM 退出时,进行删除
|
||||||
|
*
|
||||||
|
* @param data 文件内容
|
||||||
|
* @return 文件
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static File createTempFile(byte[] data) {
|
||||||
|
File file = createTempFile();
|
||||||
|
// 写入内容
|
||||||
|
FileUtil.writeBytes(data, file);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建临时文件,无内容
|
||||||
|
* 该文件会在 JVM 退出时,进行删除
|
||||||
|
*
|
||||||
|
* @return 文件
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static File createTempFile() {
|
||||||
|
// 创建文件,通过 UUID 保证唯一
|
||||||
|
File file = File.createTempFile(IdUtil.simpleUUID(), null);
|
||||||
|
// 标记 JVM 退出时,自动删除
|
||||||
|
file.deleteOnExit();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,18 @@
|
|||||||
<artifactId>jackson-core</artifactId>
|
<artifactId>jackson-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-net</groupId>
|
||||||
|
<artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 -->
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jcraft</groupId>
|
||||||
|
<artifactId>jsch</artifactId> <!-- 解决 sftp 连接 -->
|
||||||
|
<version>0.1.55</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- 三方云服务相关 -->
|
<!-- 三方云服务相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>software.amazon.awssdk</groupId>
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.impl;
|
package cn.iocoder.yudao.framework.file.core.client.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -55,4 +56,16 @@ public abstract class AbstractFileClient<Config extends FileClientConfig> implem
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化文件的 URL 访问地址
|
||||||
|
* 使用场景:local、ftp、db,通过 FileController 的 getFile 来获取文件内容
|
||||||
|
*
|
||||||
|
* @param domain 自定义域名
|
||||||
|
* @param path 文件路径
|
||||||
|
* @return URL 访问地址
|
||||||
|
*/
|
||||||
|
protected String formatFileUrl(String domain, String path) {
|
||||||
|
return StrUtil.format("{}/system-api/{}/get/{}", domain, getId(), path);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.impl.ftp;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.extra.ftp.Ftp;
|
||||||
|
import cn.hutool.extra.ftp.FtpException;
|
||||||
|
import cn.hutool.extra.ftp.FtpMode;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.AbstractFileClient;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ftp 文件客户端
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> {
|
||||||
|
|
||||||
|
private Ftp ftp;
|
||||||
|
|
||||||
|
public FtpFileClient(Long id, FtpFileClientConfig config) {
|
||||||
|
super(id, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doInit() {
|
||||||
|
// 补全风格。例如说 Linux 是 /,Windows 是 \
|
||||||
|
if (!config.getBasePath().endsWith(File.separator)) {
|
||||||
|
config.setBasePath(config.getBasePath() + File.separator);
|
||||||
|
}
|
||||||
|
// 初始化 Ftp 对象
|
||||||
|
this.ftp = new Ftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(),
|
||||||
|
CharsetUtil.CHARSET_UTF_8, null, null, FtpMode.valueOf(config.getMode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String upload(byte[] content, String path) {
|
||||||
|
// 执行写入
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
String fileName = FileUtil.getName(filePath);
|
||||||
|
String dir = StrUtil.removeSuffix(filePath, fileName);
|
||||||
|
boolean success = ftp.upload(dir, fileName, new ByteArrayInputStream(content));
|
||||||
|
if (!success) {
|
||||||
|
throw new FtpException(StrUtil.format("上海文件到目标目录 ({}) 失败", filePath));
|
||||||
|
}
|
||||||
|
// 拼接返回路径
|
||||||
|
return super.formatFileUrl(config.getDomain(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String path) {
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
ftp.delFile(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getContent(String path) {
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
String fileName = FileUtil.getName(filePath);
|
||||||
|
String dir = StrUtil.removeSuffix(path, fileName);
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ftp.download(dir, fileName, out);
|
||||||
|
return out.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFilePath(String path) {
|
||||||
|
return config.getBasePath() + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.impl.ftp;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ftp 文件客户端的配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class FtpFileClientConfig implements FileClientConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础路径
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "基础路径不能为空")
|
||||||
|
private String basePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义域名
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "domain 不能为空")
|
||||||
|
@URL(message = "domain 必须是 URL 格式")
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主机地址
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "host 不能为空")
|
||||||
|
private String host;
|
||||||
|
/**
|
||||||
|
* 主机端口
|
||||||
|
*/
|
||||||
|
@NotNull(message = "port 不能为空")
|
||||||
|
private Integer port;
|
||||||
|
/**
|
||||||
|
* 用户名
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "用户名不能为空")
|
||||||
|
private String username;
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "密码不能为空")
|
||||||
|
private String password;
|
||||||
|
/**
|
||||||
|
* 连接模式
|
||||||
|
*
|
||||||
|
* 使用 {@link cn.hutool.extra.ftp.FtpMode} 对应的字符串
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "连接模式不能为空")
|
||||||
|
private String mode;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.impl.local;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.AbstractFileClient;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地文件客户端
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class LocalFileClient extends AbstractFileClient<LocalFileClientConfig> {
|
||||||
|
|
||||||
|
public LocalFileClient(Long id, LocalFileClientConfig config) {
|
||||||
|
super(id, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doInit() {
|
||||||
|
// 补全风格。例如说 Linux 是 /,Windows 是 \
|
||||||
|
if (!config.getBasePath().endsWith(File.separator)) {
|
||||||
|
config.setBasePath(config.getBasePath() + File.separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String upload(byte[] content, String path) {
|
||||||
|
// 执行写入
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
FileUtil.writeBytes(content, filePath);
|
||||||
|
// 拼接返回路径
|
||||||
|
return super.formatFileUrl(config.getDomain(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String path) {
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
FileUtil.del(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getContent(String path) {
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
return FileUtil.readBytes(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFilePath(String path) {
|
||||||
|
return config.getBasePath() + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.impl.local;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地文件客户端的配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LocalFileClientConfig implements FileClientConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础路径
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "基础路径不能为空")
|
||||||
|
private String basePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义域名
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "domain 不能为空")
|
||||||
|
@URL(message = "domain 必须是 URL 格式")
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
}
|
@ -7,6 +7,8 @@ import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
|||||||
import software.amazon.awssdk.core.sync.RequestBody;
|
import software.amazon.awssdk.core.sync.RequestBody;
|
||||||
import software.amazon.awssdk.regions.Region;
|
import software.amazon.awssdk.regions.Region;
|
||||||
import software.amazon.awssdk.services.s3.S3Client;
|
import software.amazon.awssdk.services.s3.S3Client;
|
||||||
|
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||||
|
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||||
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -14,7 +16,7 @@ import java.net.URI;
|
|||||||
import static cn.iocoder.yudao.framework.file.core.client.impl.s3.S3FileClientConfig.ENDPOINT_QINIU;
|
import static cn.iocoder.yudao.framework.file.core.client.impl.s3.S3FileClientConfig.ENDPOINT_QINIU;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 S3 协议,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
|
* 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
|
||||||
*
|
*
|
||||||
* S3 协议的客户端,采用亚马逊提供的 software.amazon.awssdk.s3 库
|
* S3 协议的客户端,采用亚马逊提供的 software.amazon.awssdk.s3 库
|
||||||
*
|
*
|
||||||
@ -84,12 +86,18 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(String path) {
|
public void delete(String path) {
|
||||||
|
DeleteObjectRequest.Builder request = DeleteObjectRequest.builder()
|
||||||
|
.bucket(config.getBucket()) // bucket 必须传递
|
||||||
|
.key(path); // 相对路径作为 key
|
||||||
|
client.deleteObject(request.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getContent(String path) {
|
public byte[] getContent(String path) {
|
||||||
return new byte[0];
|
GetObjectRequest.Builder request = GetObjectRequest.builder()
|
||||||
|
.bucket(config.getBucket()) // bucket 必须传递
|
||||||
|
.key(path); // 相对路径作为 key
|
||||||
|
return client.getObjectAsBytes(request.build()).asByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.impl.sftp;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.extra.ssh.Sftp;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.AbstractFileClient;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sftp 文件客户端
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> {
|
||||||
|
|
||||||
|
private Sftp sftp;
|
||||||
|
|
||||||
|
public SftpFileClient(Long id, SftpFileClientConfig config) {
|
||||||
|
super(id, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doInit() {
|
||||||
|
// 补全风格。例如说 Linux 是 /,Windows 是 \
|
||||||
|
if (!config.getBasePath().endsWith(File.separator)) {
|
||||||
|
config.setBasePath(config.getBasePath() + File.separator);
|
||||||
|
}
|
||||||
|
// 初始化 Ftp 对象
|
||||||
|
this.sftp = new Sftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String upload(byte[] content, String path) {
|
||||||
|
// 执行写入
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
File file = FileUtils.createTempFile(content);
|
||||||
|
sftp.upload(filePath, file);
|
||||||
|
// 拼接返回路径
|
||||||
|
return super.formatFileUrl(config.getDomain(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String path) {
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
sftp.delFile(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getContent(String path) {
|
||||||
|
String filePath = getFilePath(path);
|
||||||
|
File destFile = FileUtils.createTempFile();
|
||||||
|
sftp.download(filePath, destFile);
|
||||||
|
return FileUtil.readBytes(destFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFilePath(String path) {
|
||||||
|
return config.getBasePath() + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.impl.sftp;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sftp 文件客户端的配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SftpFileClientConfig implements FileClientConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础路径
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "基础路径不能为空")
|
||||||
|
private String basePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义域名
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "domain 不能为空")
|
||||||
|
@URL(message = "domain 必须是 URL 格式")
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主机地址
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "host 不能为空")
|
||||||
|
private String host;
|
||||||
|
/**
|
||||||
|
* 主机端口
|
||||||
|
*/
|
||||||
|
@NotNull(message = "port 不能为空")
|
||||||
|
private Integer port;
|
||||||
|
/**
|
||||||
|
* 用户名
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "用户名不能为空")
|
||||||
|
private String username;
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "密码不能为空")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.ftp;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.extra.ftp.FtpMode;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.ftp.FtpFileClient;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.ftp.FtpFileClientConfig;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class FtpFileClientTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
// 创建客户端
|
||||||
|
FtpFileClientConfig config = new FtpFileClientConfig();
|
||||||
|
config.setDomain("http://127.0.0.1:48080");
|
||||||
|
config.setBasePath("/home/ftp");
|
||||||
|
config.setHost("kanchai.club");
|
||||||
|
config.setPort(221);
|
||||||
|
config.setUsername("");
|
||||||
|
config.setPassword("");
|
||||||
|
config.setMode(FtpMode.Passive.name());
|
||||||
|
FtpFileClient client = new FtpFileClient(0L, config);
|
||||||
|
client.init();
|
||||||
|
// 上传文件
|
||||||
|
String path = IdUtil.fastSimpleUUID() + ".jpg";
|
||||||
|
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
|
||||||
|
String fullPath = client.upload(content, path);
|
||||||
|
System.out.println("访问地址:" + fullPath);
|
||||||
|
if (false) {
|
||||||
|
byte[] bytes = client.getContent(path);
|
||||||
|
System.out.println("文件内容:" + bytes);
|
||||||
|
}
|
||||||
|
if (false) {
|
||||||
|
client.delete(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.local;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.local.LocalFileClient;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.local.LocalFileClientConfig;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class LocalFileClientTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
// 创建客户端
|
||||||
|
LocalFileClientConfig config = new LocalFileClientConfig();
|
||||||
|
config.setDomain("http://127.0.0.1:48080");
|
||||||
|
config.setBasePath("/Users/yunai/file_test");
|
||||||
|
LocalFileClient client = new LocalFileClient(0L, config);
|
||||||
|
client.init();
|
||||||
|
// 上传文件
|
||||||
|
String path = IdUtil.fastSimpleUUID() + ".jpg";
|
||||||
|
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
|
||||||
|
String fullPath = client.upload(content, path);
|
||||||
|
System.out.println("访问地址:" + fullPath);
|
||||||
|
client.delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -76,6 +76,15 @@ public class S3FileClientTest {
|
|||||||
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
|
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
|
||||||
String fullPath = client.upload(content, path);
|
String fullPath = client.upload(content, path);
|
||||||
System.out.println("访问地址:" + fullPath);
|
System.out.println("访问地址:" + fullPath);
|
||||||
|
// 读取文件
|
||||||
|
if (false) {
|
||||||
|
byte[] bytes = client.getContent(path);
|
||||||
|
System.out.println("文件内容:" + bytes);
|
||||||
|
}
|
||||||
|
// 删除文件
|
||||||
|
if (false) {
|
||||||
|
client.delete(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.sftp;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.sftp.SftpFileClient;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.impl.sftp.SftpFileClientConfig;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class SftpFileClientTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
// 创建客户端
|
||||||
|
SftpFileClientConfig config = new SftpFileClientConfig();
|
||||||
|
config.setDomain("http://127.0.0.1:48080");
|
||||||
|
config.setBasePath("/home/ftp");
|
||||||
|
config.setHost("kanchai.club");
|
||||||
|
config.setPort(222);
|
||||||
|
config.setUsername("");
|
||||||
|
config.setPassword("");
|
||||||
|
SftpFileClient client = new SftpFileClient(0L, config);
|
||||||
|
client.init();
|
||||||
|
// 上传文件
|
||||||
|
String path = IdUtil.fastSimpleUUID() + ".jpg";
|
||||||
|
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
|
||||||
|
String fullPath = client.upload(content, path);
|
||||||
|
System.out.println("访问地址:" + fullPath);
|
||||||
|
if (false) {
|
||||||
|
byte[] bytes = client.getContent(path);
|
||||||
|
System.out.println("文件内容:" + bytes);
|
||||||
|
}
|
||||||
|
if (false) {
|
||||||
|
client.delete(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -57,10 +57,15 @@ public class FileController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get/{path}")
|
@GetMapping("/{configId}/get/{path}")
|
||||||
@ApiOperation("下载文件")
|
@ApiOperation("下载文件")
|
||||||
@ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class)
|
@ApiImplicitParams({
|
||||||
public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException {
|
@ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = String.class),
|
||||||
|
@ApiImplicitParam(name = "path", value = "文件路径", required = true, dataTypeClass = String.class)
|
||||||
|
})
|
||||||
|
public void getFile(HttpServletResponse response,
|
||||||
|
@PathVariable("configId") String configId,
|
||||||
|
@PathVariable("path") String path) throws IOException {
|
||||||
FileDO file = fileService.getFile(path);
|
FileDO file = fileService.getFile(path);
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
log.warn("[getFile][path({}) 文件不存在]", path);
|
log.warn("[getFile][path({}) 文件不存在]", path);
|
||||||
|
Loading…
Reference in New Issue
Block a user