From f6090690fd5bd8b5286a398d12b8bc27012d148b Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 27 Nov 2025 15:42:41 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E3=80=90infra=20=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E8=AE=BE=E6=96=BD=E3=80=91S3FileClient=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=9A=84=20region=20>=20=E4=BB=8E=20endpoint=20=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=9A=84=20region=20>=20=E9=BB=98=E8=AE=A4=E5=80=BC?= =?UTF-8?q?=20us-east-1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../file/core/client/s3/S3FileClient.java | 76 ++++++++++++++++++- .../core/client/s3/S3FileClientConfig.java | 12 +++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClient.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClient.java index 94ba6a3ebb..e7b8b9789a 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClient.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClient.java @@ -47,7 +47,9 @@ public class S3FileClient extends AbstractFileClient { 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()); @@ -159,4 +161,76 @@ public class S3FileClient extends AbstractFileClient { 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. 尝试从 endpoint 中解析 region + String endpoint = config.getEndpoint(); + if (StrUtil.isEmpty(endpoint)) { + return "us-east-1"; + } + + // 移除协议头(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. 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"; + } + + // 4. 阿里云 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; + } + } + } + + // 5. 腾讯云 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; + } + } + } + + // 6. 其他情况(MinIO、七牛云等)使用默认值 + return "us-east-1"; + } + } diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClientConfig.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClientConfig.java index 216197964a..a0760c40f2 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClientConfig.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClientConfig.java @@ -82,6 +82,18 @@ public class S3FileClientConfig implements FileClientConfig { @NotNull(message = "是否公开访问不能为空") private Boolean enablePublicAccess; + /** + * AWS 区域 + * 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