update 优化 oss 模块代码实现

This commit is contained in:
疯狂的狮子Li
2026-03-27 17:09:17 +08:00
parent d5003d81ed
commit 48dcd00191
7 changed files with 343 additions and 133 deletions

View File

@@ -2,20 +2,25 @@ package org.dromara.common.oss.client;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.oss.config.OssClientConfig;
import org.dromara.common.oss.exception.S3StorageException;
import org.dromara.common.oss.io.OutputStreamDownloadSubscriber;
import org.dromara.common.oss.model.GetObjectResult;
import org.dromara.common.oss.model.HandleAsyncResult;
import org.dromara.common.oss.model.Options;
import org.dromara.common.oss.model.PutObjectResult;
import org.jspecify.annotations.NullMarked;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.core.async.ResponsePublisher;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.*;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedUpload;
@@ -24,8 +29,8 @@ import software.amazon.awssdk.transfer.s3.progress.TransferListener;
import java.io.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -46,7 +51,6 @@ import java.util.function.Function;
*
* @author 秋辞未寒
*/
@Slf4j
public abstract class AbstractOssClientImpl implements OssClient {
private final AtomicBoolean initialized = new AtomicBoolean(false);
@@ -127,27 +131,6 @@ public abstract class AbstractOssClientImpl implements OssClient {
abstract void doInitialize();
@Override
public void refresh(OssClientConfig config) {
if (Objects.equals(this.config, config)) {
return;
}
// 如果状态本来就是未初始化,直接则调用初始化
if (!initialized.get()) {
this.initialize();
}
// 将状态转为未初始化
if (initialized.compareAndSet(false, true)) {
try {
this.close();
} catch (Exception e) {
// 异常不影响刷新逻辑,此处屏蔽异常
}
// 状态交换成功才进行刷新
this.initialize();
}
}
@Override
public boolean verifyConfig(Function<OssClientConfig, Boolean> verifyConfigAction) {
OssClientConfig config = config();
@@ -159,6 +142,23 @@ public abstract class AbstractOssClientImpl implements OssClient {
return verifyConfig((config) -> Objects.equals(config, verifyConfig));
}
@Override
public String buildPathKey(String fileName) {
return buildPathKey(null, fileName);
}
@Override
public String buildPathKey(String businessPrefix, String fileName) {
String defaultPrefix = config.prefix()
.orElse("");
String mergedPrefix = mergePrefix(defaultPrefix, businessPrefix);
String suffix = suffix(fileName);
String datePath = DateUtils.datePath();
String uuid = IdUtil.fastSimpleUUID();
String path = mergedPrefix.isEmpty() ? datePath + StringUtils.SLASH + uuid : mergedPrefix + StringUtils.SLASH + datePath + StringUtils.SLASH + uuid;
return path + suffix;
}
@Override
public <T> T doCustomUpload(AsyncRequestBody body, Consumer<PutObjectRequest.Builder> putObjectRequestBuilderConsumer, Collection<TransferListener> transferListeners, BiFunction<CompletedUpload, Throwable, T> handleAsyncAction) {
try {
@@ -204,21 +204,57 @@ public abstract class AbstractOssClientImpl implements OssClient {
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, Path path) {
public PutObjectResult bucketUpload(String bucket, String key, Path path, Options options) {
AsyncRequestBody body = AsyncRequestBody.fromFile(path);
return bucketUpload(bucket, key, body);
return bucketUpload(bucket, key, body, options);
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, Path path) {
return bucketUpload(bucket, key, path, Options.builder());
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, File file, Options options) {
AsyncRequestBody body = AsyncRequestBody.fromFile(file);
return bucketUpload(bucket, key, body, options);
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, File file) {
AsyncRequestBody body = AsyncRequestBody.fromFile(file);
return bucketUpload(bucket, key, body);
return bucketUpload(bucket, key, file, Options.builder());
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, RandomAccessFile file, Options options) {
try {
// 以文件的大小为准
options.setLength(file.length());
return bucketUpload(bucket, key, file.getChannel(), -1L, options);
} catch (Exception e) {
if (e instanceof S3StorageException ex) {
throw ex;
}
throw S3StorageException.form(e);
}
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, RandomAccessFile file) {
return bucketUpload(bucket, key, file, Options.builder());
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, ReadableByteChannel channel, long contentLength, Options options) {
// 让调用者自行处理通道的关闭
InputStream in = Channels.newInputStream(channel);
try {
return bucketUpload(bucket, key, file.getChannel(), -1L);
// 如果可以实时获取文件大小,则优先是有实时获取的
long size = contentLength;
if (channel instanceof SeekableByteChannel byteChannel) {
size = byteChannel.size();
}
return bucketUpload(bucket, key, in, size, options);
} catch (Exception e) {
if (e instanceof S3StorageException ex) {
throw ex;
@@ -229,30 +265,25 @@ public abstract class AbstractOssClientImpl implements OssClient {
@Override
public PutObjectResult bucketUpload(String bucket, String key, ReadableByteChannel channel, long contentLength) {
long size = contentLength;
try (channel; InputStream in = Channels.newInputStream(channel)) {
if (channel instanceof FileChannel fileChannel) {
size = fileChannel.size();
}
return bucketUpload(bucket, key, in, size);
} catch (Exception e) {
if (e instanceof S3StorageException ex) {
throw ex;
}
throw S3StorageException.form(e);
}
return bucketUpload(bucket, key, channel, contentLength, Options.builder());
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, InputStream in, long contentLength, Options options) {
options.setLength(contentLength);
AsyncRequestBody body = AsyncRequestBody.fromInputStream(in, contentLength, asyncExecutor);
return bucketUpload(bucket, key, body, options);
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, InputStream in, long contentLength) {
AsyncRequestBody body = AsyncRequestBody.fromInputStream(in, contentLength, asyncExecutor);
return bucketUpload(bucket, key, body);
return bucketUpload(bucket, key, in, contentLength, Options.builder());
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, byte[] data) {
public PutObjectResult bucketUpload(String bucket, String key, byte[] data, Options options) {
try (ByteArrayInputStream in = new ByteArrayInputStream(data)) {
return bucketUpload(bucket, key, in, data.length);
return bucketUpload(bucket, key, in, data.length, options);
} catch (Exception e) {
if (e instanceof S3StorageException ex) {
throw ex;
@@ -261,15 +292,28 @@ public abstract class AbstractOssClientImpl implements OssClient {
}
}
@Override
public PutObjectResult bucketUpload(String bucket, String key, byte[] data) {
return bucketUpload(bucket, key, data, Options.builder());
}
private PutObjectResult bucketUpload(String bucket, String key, AsyncRequestBody body) {
Long contentLength = body.contentLength().orElse(null);
@NullMarked
private PutObjectResult bucketUpload(String bucket, String key, AsyncRequestBody body, Options options) {
// 优先使用body中的内容大小如果不存在再获取可选项中的
Long contentLength = body.contentLength().orElse(options.getLength());
// 优先使用body中的内容类型如果不存在再获取可选项中的
String contentType = StringUtils.isBlank(options.getContentType()) ? body.contentType() : options.getContentType();
String md5Digest = options.getMd5Digest();
Map<String, String> metadata = options.getMetadata();
Collection<TransferListener> transferListeners = options.getTransferListeners();
HandleAsyncResult<PutObjectResponse> result = doCustomUpload(body, builder -> {
builder.bucket(bucket)
.key(key)
.contentMD5(md5Digest)
.contentType(contentType)
.contentLength(contentLength)
;
});
.metadata(metadata);
}, transferListeners);
if (result.isFailure()) {
throw S3StorageException.form(result.error());
}
@@ -278,11 +322,13 @@ public abstract class AbstractOssClientImpl implements OssClient {
throw S3StorageException.form("response is empty.");
}
PutObjectResponse response = opt.get();
String bucketUrl = config.getBucketUrl(bucket);
// 不知道什么原因导致 response.size() 返回了一个 null size ,此处做一个适配...
Long size = response.size();
size = size == null ? contentLength : size;
return PutObjectResult.form("%s/%s".formatted(bucketUrl, key), key, response.eTag(), size == null ? 0 : size);
if (size == null) {
size = contentLength == null ? 0 : contentLength;
}
String bucketUrl = config.getBucketUrl(bucket);
return PutObjectResult.form("%s/%s".formatted(bucketUrl, key), key, response.eTag(), size);
}
@Override
@@ -392,8 +438,8 @@ public abstract class AbstractOssClientImpl implements OssClient {
@Override
public boolean bucketDelete(String bucket, String key) {
try {
DeleteObjectResponse response = s3AsyncClient.deleteObject(builder -> builder.bucket(bucket).key(key)).join();
return Boolean.TRUE.equals(response.deleteMarker());
s3AsyncClient.deleteObject(builder -> builder.bucket(bucket).key(key)).join();
return true;
} catch (Exception e) {
throw S3StorageException.form(e);
}
@@ -427,31 +473,61 @@ public abstract class AbstractOssClientImpl implements OssClient {
}
}
@Override
public PutObjectResult upload(String key, Path path, Options options) {
return bucketUpload(defaultBucket(), key, path, options);
}
@Override
public PutObjectResult upload(String key, Path path) {
return bucketUpload(defaultBucket(), key, path);
}
@Override
public PutObjectResult upload(String key, File file, Options options) {
return bucketUpload(defaultBucket(), key, file, options);
}
@Override
public PutObjectResult upload(String key, File file) {
return bucketUpload(defaultBucket(), key, file);
}
@Override
public PutObjectResult upload(String key, RandomAccessFile file, Options options) {
return bucketUpload(defaultBucket(), key, file, options);
}
@Override
public PutObjectResult upload(String key, RandomAccessFile file) {
return bucketUpload(defaultBucket(), key, file);
}
@Override
public PutObjectResult upload(String key, ReadableByteChannel channel, long contentLength, Options options) {
return bucketUpload(defaultBucket(), key, channel, contentLength, options);
}
@Override
public PutObjectResult upload(String key, ReadableByteChannel channel, long contentLength) {
return bucketUpload(defaultBucket(), key, channel, contentLength);
}
@Override
public PutObjectResult upload(String key, InputStream in, long contentLength, Options options) {
return bucketUpload(defaultBucket(), key, in, contentLength, options);
}
@Override
public PutObjectResult upload(String key, InputStream in, long contentLength) {
return bucketUpload(defaultBucket(), key, in, contentLength);
}
@Override
public PutObjectResult upload(String key, byte[] data, Options options) {
return bucketUpload(defaultBucket(), key, data, options);
}
@Override
public PutObjectResult upload(String key, byte[] data) {
return bucketUpload(defaultBucket(), key, data);
@@ -513,6 +589,43 @@ public abstract class AbstractOssClientImpl implements OssClient {
.orElseThrow(() -> S3StorageException.form("bucket is not configured."));
}
private String mergePrefix(String defaultPrefix, String businessPrefix) {
String left = normalizePrefix(defaultPrefix);
String right = normalizePrefix(businessPrefix);
if (left.isEmpty()) {
return right;
}
if (right.isEmpty()) {
return left;
}
return left + StringUtils.SLASH + right;
}
private String normalizePrefix(String prefix) {
if (prefix == null) {
return "";
}
String normalized = prefix.trim();
while (normalized.startsWith(StringUtils.SLASH)) {
normalized = normalized.substring(1);
}
while (normalized.endsWith(StringUtils.SLASH)) {
normalized = normalized.substring(0, normalized.length() - 1);
}
return normalized;
}
private String suffix(String fileName) {
if (fileName == null) {
return "";
}
int index = fileName.lastIndexOf('.');
if (index < 0) {
return "";
}
return fileName.substring(index);
}
@Override
public void close() throws Exception {
if (s3TransferManager != null) {

View File

@@ -5,6 +5,7 @@ import org.dromara.common.oss.config.OssClientConfig;
import org.dromara.common.oss.io.OutputStreamDownloadSubscriber;
import org.dromara.common.oss.model.GetObjectResult;
import org.dromara.common.oss.model.HandleAsyncResult;
import org.dromara.common.oss.model.Options;
import org.dromara.common.oss.model.PutObjectResult;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
@@ -67,13 +68,6 @@ public interface OssClient extends AutoCloseable {
*/
void initialize();
/**
* 刷新客户端配置
*
* @param config 配置项
*/
void refresh(OssClientConfig config);
/**
* 校验客户端配置
*
@@ -136,6 +130,17 @@ public interface OssClient extends AutoCloseable {
*/
HandleAsyncResult<PutObjectResponse> doCustomUpload(AsyncRequestBody body, Consumer<PutObjectRequest.Builder> putObjectRequestBuilderConsumer);
/**
* 将本地路径对应的文件上传到指定存储桶。
*
* @param bucket 存储桶名称
* @param key 对象键
* @param path 文件路径
* @param options 可选项
* @return 上传结果
*/
PutObjectResult bucketUpload(String bucket, String key, Path path, Options options);
/**
* 将本地路径对应的文件上传到指定存储桶。
*
@@ -146,6 +151,17 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult bucketUpload(String bucket, String key, Path path);
/**
* 将文件上传到指定存储桶。
*
* @param bucket 存储桶名称
* @param key 对象键
* @param file 文件对象
* @param options 可选项
* @return 上传结果
*/
PutObjectResult bucketUpload(String bucket, String key, File file, Options options);
/**
* 将文件上传到指定存储桶。
*
@@ -156,6 +172,17 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult bucketUpload(String bucket, String key, File file);
/**
* 将随机访问文件上传到指定存储桶。
*
* @param bucket 存储桶名称
* @param key 对象键
* @param file 随机访问文件
* @param options 可选项
* @return 上传结果
*/
PutObjectResult bucketUpload(String bucket, String key, RandomAccessFile file, Options options);
/**
* 将随机访问文件上传到指定存储桶。
*
@@ -166,6 +193,18 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult bucketUpload(String bucket, String key, RandomAccessFile file);
/**
* 将可读通道中的数据上传到指定存储桶。
*
* @param bucket 存储桶名称
* @param key 对象键
* @param channel 数据通道
* @param contentLength 内容长度
* @param options 可选项
* @return 上传结果
*/
PutObjectResult bucketUpload(String bucket, String key, ReadableByteChannel channel, long contentLength, Options options);
/**
* 将可读通道中的数据上传到指定存储桶。
*
@@ -177,6 +216,18 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult bucketUpload(String bucket, String key, ReadableByteChannel channel, long contentLength);
/**
* 将可读通道中的数据上传到指定存储桶。
*
* @param bucket 存储桶名称
* @param key 对象键
* @param in 输入流
* @param contentLength 内容长度
* @param options 可选项
* @return 上传结果
*/
PutObjectResult bucketUpload(String bucket, String key, InputStream in, long contentLength, Options options);
/**
* 将输入流中的数据上传到指定存储桶。
*
@@ -188,6 +239,17 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult bucketUpload(String bucket, String key, InputStream in, long contentLength);
/**
* 将字节数组上传到指定存储桶。
*
* @param bucket 存储桶名称
* @param key 对象键
* @param data 字节数组
* @param options 可选项
* @return 上传结果
*/
PutObjectResult bucketUpload(String bucket, String key, byte[] data, Options options);
/**
* 将字节数组上传到指定存储桶。
*
@@ -309,6 +371,16 @@ public interface OssClient extends AutoCloseable {
*/
String bucketPresignPutUrl(String bucket, String key, Duration expiredTime, Map<String, String> metadata);
/**
* 将本地路径对应的文件上传到默认存储桶。
*
* @param key 对象键
* @param path 文件路径
* @param options 可选项
* @return 上传结果
*/
PutObjectResult upload(String key, Path path, Options options);
/**
* 将本地路径对应的文件上传到默认存储桶。
*
@@ -318,6 +390,16 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult upload(String key, Path path);
/**
* 将文件上传到默认存储桶。
*
* @param key 对象键
* @param file 文件对象
* @param options 可选项
* @return 上传结果
*/
PutObjectResult upload(String key, File file, Options options);
/**
* 将文件上传到默认存储桶。
*
@@ -327,6 +409,16 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult upload(String key, File file);
/**
* 将随机访问文件上传到默认存储桶。
*
* @param key 对象键
* @param file 随机访问文件
* @param options 可选项
* @return 上传结果
*/
PutObjectResult upload(String key, RandomAccessFile file, Options options);
/**
* 将随机访问文件上传到默认存储桶。
*
@@ -336,6 +428,17 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult upload(String key, RandomAccessFile file);
/**
* 将可读通道中的数据上传到默认存储桶。
*
* @param key 对象键
* @param channel 数据通道
* @param contentLength 内容长度
* @param options 可选项
* @return 上传结果
*/
PutObjectResult upload(String key, ReadableByteChannel channel, long contentLength, Options options);
/**
* 将可读通道中的数据上传到默认存储桶。
*
@@ -346,6 +449,17 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult upload(String key, ReadableByteChannel channel, long contentLength);
/**
* 将输入流中的数据上传到默认存储桶。
*
* @param key 对象键
* @param in 输入流
* @param contentLength 内容长度
* @param options 可选项
* @return 上传结果
*/
PutObjectResult upload(String key, InputStream in, long contentLength, Options options);
/**
* 将输入流中的数据上传到默认存储桶。
*
@@ -356,6 +470,16 @@ public interface OssClient extends AutoCloseable {
*/
PutObjectResult upload(String key, InputStream in, long contentLength);
/**
* 将字节数组上传到默认存储桶。
*
* @param key 对象键
* @param data 字节数组
* @param options 可选项
* @return 上传结果
*/
PutObjectResult upload(String key, byte[] data, Options options);
/**
* 将字节数组上传到默认存储桶。
*
@@ -454,4 +578,21 @@ public interface OssClient extends AutoCloseable {
* @return 预签名上传 URL
*/
String presignPutUrl(String key, Duration expiredTime, Map<String, String> metadata);
/**
* 根据客户端配置生成默认对象Key。
*
* @param fileName 原始文件名
* @return 对象Key
*/
String buildPathKey(String fileName);
/**
* 根据业务前缀和客户端默认前缀生成对象Key。
*
* @param businessPrefix 业务前缀
* @param fileName 原始文件名
* @return 对象Key
*/
String buildPathKey(String businessPrefix, String fileName);
}

View File

@@ -182,6 +182,7 @@ public class OssClientConfig implements Config<OssClientConfig, OssClientConfig.
.secretKey(properties.getSecretKey())
.bucket(properties.getBucketName())
.region(region)
.prefix(properties.getPrefix())
.useHttps(SystemConstants.YES.equals(properties.getIsHttps()))
.usePathStyleAccess(usePathStyleAccess)
.accessControlPolicyConfig(accessControlPolicyConfig);

View File

@@ -52,21 +52,18 @@ public class OssFactory {
OssClientConfig config = OssClientConfig.formProperties(properties);
LOCK.lock();
try {
// 如果已经存在,则校验配置一致性
if (CLIENT_CACHE.containsKey(configKey)) {
OssClient client = CLIENT_CACHE.get(configKey);
if (!client.verifyConfig(config)) {
// 配置不一致,刷新配置
client.refresh(config);
CLIENT_CACHE.put(configKey, client);
OssClient client = CLIENT_CACHE.get(configKey);
if (client != null) {
if (client.verifyConfig(config)) {
return client;
}
return client;
closeClient(configKey, client);
}
DefaultOssClientImpl client = new DefaultOssClientImpl(configKey, config);
CLIENT_CACHE.put(configKey, client);
return client;
OssClient newClient = new DefaultOssClientImpl(configKey, config);
CLIENT_CACHE.put(configKey, newClient);
return newClient;
} finally {
LOCK.lock();
LOCK.unlock();
}
}
@@ -78,12 +75,16 @@ public class OssFactory {
if (client == null) {
return false;
}
try {
client.close();
} catch (Exception e) {
log.warn("S3存储客户端关闭异常错误信息: {}", e.getMessage(), e);
}
closeClient(configKey, client);
return true;
}
private static void closeClient(String configKey, OssClient client) {
try {
client.close();
} catch (Exception e) {
log.warn("S3存储客户端 [{}] 关闭异常,错误信息: {}", configKey, e.getMessage(), e);
}
}
}

View File

@@ -1,46 +0,0 @@
package org.dromara.common.oss.util;
import cn.hutool.core.util.IdUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
/**
* S3文件对象工具类
*
* @author 秋辞未寒
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class S3ObjectUtil {
/**
* 生成一个 【自定义前缀 + 日期路径 + SimpleUUID.文件后缀】 的对象Key 示例: images/20260321/019d0f89c9b1130a48c90dbca0475a.jpg
*
* @param prefix 前缀
* @param withSuffixFileName 带后缀的文件名
* @return 文件路径对象Key
*/
public static String buildPathKey(String prefix, String withSuffixFileName) {
// 获取后缀
String suffix = StringUtils.substring(withSuffixFileName, withSuffixFileName.lastIndexOf("."), withSuffixFileName.length());
// 生成日期路径
String datePath = DateUtils.datePath();
// 生成uuid
String uuid = IdUtil.fastSimpleUUID();
// 拼接路径
String path = StringUtils.isNotEmpty(prefix) ? prefix + StringUtils.SLASH + datePath + StringUtils.SLASH + uuid : datePath + StringUtils.SLASH + uuid;
return path + suffix;
}
/**
* 生成一个 【日期路径 + SimpleUUID.文件后缀】 的对象Key 示例: 20260321/019d0f89c9b1130a48c90dbca0475a.jpg
*
* @param withSuffixFileName 带后缀的文件名
* @return 文件路径对象Key
*/
public static String buildPathKey(String withSuffixFileName) {
return buildPathKey("", withSuffixFileName);
}
}

View File

@@ -11,7 +11,6 @@ import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.oss.client.OssClient;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.common.oss.model.PutObjectResult;
import org.dromara.common.oss.util.S3ObjectUtil;
import org.dromara.resource.api.RemoteFileService;
import org.dromara.resource.api.domain.RemoteFile;
import org.dromara.resource.domain.SysOssExt;
@@ -45,7 +44,7 @@ public class RemoteFileServiceImpl implements RemoteFileService {
try {
String suffix = StringUtils.substring(originalFilename, originalFilename.lastIndexOf("."), originalFilename.length());
OssClient instance = OssFactory.instance();
String pathKey = S3ObjectUtil.buildPathKey(originalFilename);
String pathKey = instance.buildPathKey(originalFilename);
PutObjectResult result = instance.upload(pathKey, file);
// 保存文件信息
SysOssBo oss = new SysOssBo();

View File

@@ -21,8 +21,8 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.oss.client.OssClient;
import org.dromara.common.oss.enums.AccessPolicy;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.common.oss.model.Options;
import org.dromara.common.oss.model.PutObjectResult;
import org.dromara.common.oss.util.S3ObjectUtil;
import org.dromara.resource.domain.SysOss;
import org.dromara.resource.domain.SysOssExt;
import org.dromara.resource.domain.bo.SysOssBo;
@@ -38,6 +38,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
@@ -194,9 +195,9 @@ public class SysOssServiceImpl implements ISysOssService {
String originalfileName = file.getOriginalFilename();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient instance = OssFactory.instance();
try {
String pathKey = S3ObjectUtil.buildPathKey(originalfileName);
PutObjectResult result = instance.upload(pathKey, file.getInputStream(), file.getSize());
String pathKey = instance.buildPathKey(originalfileName);
try (InputStream inputStream = file.getInputStream()) {
PutObjectResult result = instance.upload(pathKey, inputStream, file.getSize(), Options.builder().setContentType(file.getContentType()));
SysOssExt ext1 = new SysOssExt();
ext1.setFileSize(file.getSize());
ext1.setContentType(file.getContentType());
@@ -221,8 +222,8 @@ public class SysOssServiceImpl implements ISysOssService {
String originalfileName = file.getName();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient instance = OssFactory.instance();
String pathKey = S3ObjectUtil.buildPathKey(originalfileName);
PutObjectResult result = instance.upload(pathKey, file);
String pathKey = instance.buildPathKey(originalfileName);
PutObjectResult result = instance.upload(pathKey, file, Options.builder().setContentType(FileUtils.getMimeType(file.toPath())));
SysOssExt ext1 = new SysOssExt();
ext1.setFileSize(result.size());
// 保存文件信息