【同步】BOOT 和 CLOUD 的功能
This commit is contained in:
@@ -47,7 +47,9 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
config.setDomain(buildDomain());
|
||||
}
|
||||
// 初始化 S3 客户端
|
||||
Region region = Region.of("us-east-1"); // 必须填,但填什么都行,常见的值有 "us-east-1",不填会报错
|
||||
// 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
|
||||
String regionStr = resolveRegion();
|
||||
Region region = Region.of(regionStr);
|
||||
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
|
||||
AwsBasicCredentials.create(config.getAccessKey(), config.getAccessSecret()));
|
||||
URI endpoint = URI.create(buildEndpoint());
|
||||
@@ -105,8 +107,8 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
@Override
|
||||
public String presignPutUrl(String path) {
|
||||
return presigner.presignPutObject(PutObjectPresignRequest.builder()
|
||||
.signatureDuration(EXPIRATION_DEFAULT)
|
||||
.putObjectRequest(b -> b.bucket(config.getBucket()).key(path)).build())
|
||||
.signatureDuration(EXPIRATION_DEFAULT)
|
||||
.putObjectRequest(b -> b.bucket(config.getBucket()).key(path)).build())
|
||||
.url().toString();
|
||||
}
|
||||
|
||||
@@ -114,7 +116,7 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
public String presignGetUrl(String url, Integer expirationSeconds) {
|
||||
// 1. 将 url 转换为 path
|
||||
String path = StrUtil.removePrefix(url, config.getDomain() + "/");
|
||||
path = HttpUtils.removeUrlQuery(path);
|
||||
path = HttpUtils.decodeUtf8(HttpUtils.removeUrlQuery(path));
|
||||
|
||||
// 2.1 情况一:公开访问:无需签名
|
||||
// 考虑到老版本的兼容,所以必须是 config.getEnablePublicAccess() 为 false 时,才进行签名
|
||||
@@ -126,8 +128,8 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
String finalPath = path;
|
||||
Duration expiration = expirationSeconds != null ? Duration.ofSeconds(expirationSeconds) : EXPIRATION_DEFAULT;
|
||||
URL signedUrl = presigner.presignGetObject(GetObjectPresignRequest.builder()
|
||||
.signatureDuration(expiration)
|
||||
.getObjectRequest(b -> b.bucket(config.getBucket()).key(finalPath)).build())
|
||||
.signatureDuration(expiration)
|
||||
.getObjectRequest(b -> b.bucket(config.getBucket()).key(finalPath)).build())
|
||||
.url();
|
||||
return signedUrl.toString();
|
||||
}
|
||||
@@ -159,4 +161,73 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
return StrUtil.format("https://{}", config.getEndpoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 AWS 区域
|
||||
* 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
|
||||
*
|
||||
* @return 区域字符串
|
||||
*/
|
||||
private String resolveRegion() {
|
||||
// 1. 如果配置了 region,直接使用
|
||||
if (StrUtil.isNotEmpty(config.getRegion())) {
|
||||
return config.getRegion();
|
||||
}
|
||||
|
||||
// 2.1 尝试从 endpoint 中解析 region
|
||||
String endpoint = config.getEndpoint();
|
||||
if (StrUtil.isEmpty(endpoint)) {
|
||||
return "us-east-1";
|
||||
}
|
||||
|
||||
// 2.2 移除协议头(http:// 或 https://)
|
||||
String host = endpoint;
|
||||
if (HttpUtil.isHttp(endpoint) || HttpUtil.isHttps(endpoint)) {
|
||||
try {
|
||||
host = URI.create(endpoint).getHost();
|
||||
} catch (Exception e) {
|
||||
// 解析失败,使用默认值
|
||||
return "us-east-1";
|
||||
}
|
||||
}
|
||||
if (StrUtil.isEmpty(host)) {
|
||||
return "us-east-1";
|
||||
}
|
||||
|
||||
// 3.1 AWS S3 格式:s3.us-west-2.amazonaws.com 或 s3.amazonaws.com
|
||||
if (host.contains("amazonaws.com")) {
|
||||
// 匹配 s3.{region}.amazonaws.com 格式
|
||||
if (host.startsWith("s3.") && host.contains(".amazonaws.com")) {
|
||||
String regionPart = host.substring(3, host.indexOf(".amazonaws.com"));
|
||||
if (StrUtil.isNotEmpty(regionPart) && !regionPart.equals("accelerate")) {
|
||||
return regionPart;
|
||||
}
|
||||
}
|
||||
// s3.amazonaws.com 或 s3-accelerate.amazonaws.com 使用默认值
|
||||
return "us-east-1";
|
||||
}
|
||||
// 3.2 阿里云 OSS 格式:oss-cn-beijing.aliyuncs.com
|
||||
if (host.contains(S3FileClientConfig.ENDPOINT_ALIYUN)) {
|
||||
// 匹配 oss-{region}.aliyuncs.com 格式
|
||||
if (host.startsWith("oss-") && host.contains("." + S3FileClientConfig.ENDPOINT_ALIYUN)) {
|
||||
String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_ALIYUN));
|
||||
if (StrUtil.isNotEmpty(regionPart)) {
|
||||
return regionPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3.3 腾讯云 COS 格式:cos.ap-shanghai.myqcloud.com
|
||||
if (host.contains(S3FileClientConfig.ENDPOINT_TENCENT)) {
|
||||
// 匹配 cos.{region}.myqcloud.com 格式
|
||||
if (host.startsWith("cos.") && host.contains("." + S3FileClientConfig.ENDPOINT_TENCENT)) {
|
||||
String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_TENCENT));
|
||||
if (StrUtil.isNotEmpty(regionPart)) {
|
||||
return regionPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3.4 其他情况(MinIO、七牛云等)使用默认值
|
||||
return "us-east-1";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,6 +82,18 @@ public class S3FileClientConfig implements FileClientConfig {
|
||||
@NotNull(message = "是否公开访问不能为空")
|
||||
private Boolean enablePublicAccess;
|
||||
|
||||
/**
|
||||
* 区域
|
||||
* 1. AWS S3:https://docs.aws.amazon.com/general/latest/gr/s3.html 例如说,us-east-1、us-west-2
|
||||
* 2. MinIO:可以填任意值,通常使用 us-east-1
|
||||
* 3. 阿里云:不需要填写,会自动识别
|
||||
* 4. 腾讯云:不需要填写,会自动识别
|
||||
* 5. 七牛云:不需要填写,会自动识别
|
||||
* 6. 华为云:不需要填写,会自动识别
|
||||
* 7. 火山云:不需要填写,会自动识别
|
||||
*/
|
||||
private String region;
|
||||
|
||||
@SuppressWarnings("RedundantIfStatement")
|
||||
@AssertTrue(message = "domain 不能为空")
|
||||
@JsonIgnore
|
||||
|
||||
Reference in New Issue
Block a user