Commit 94ee7d657d8c2ad2a9d21d192906ed449d52d22b
Committed by
Gitee
!1465 fix: 【infra 基础设施】S3FileClient 配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
Merge pull request !1465 from puhui999/master-jdk17
Showing
2 changed files
with
87 additions
and
1 deletions
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<S3FileClientConfig> { |
| 47 | 47 | config.setDomain(buildDomain()); |
| 48 | 48 | } |
| 49 | 49 | // 初始化 S3 客户端 |
| 50 | - Region region = Region.of("us-east-1"); // 必须填,但填什么都行,常见的值有 "us-east-1",不填会报错 | |
| 50 | + // 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1 | |
| 51 | + String regionStr = resolveRegion(); | |
| 52 | + Region region = Region.of(regionStr); | |
| 51 | 53 | AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create( |
| 52 | 54 | AwsBasicCredentials.create(config.getAccessKey(), config.getAccessSecret())); |
| 53 | 55 | URI endpoint = URI.create(buildEndpoint()); |
| ... | ... | @@ -159,4 +161,76 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { |
| 159 | 161 | return StrUtil.format("https://{}", config.getEndpoint()); |
| 160 | 162 | } |
| 161 | 163 | |
| 164 | + /** | |
| 165 | + * 解析 AWS 区域 | |
| 166 | + * 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1 | |
| 167 | + * | |
| 168 | + * @return 区域字符串 | |
| 169 | + */ | |
| 170 | + private String resolveRegion() { | |
| 171 | + // 1. 如果配置了 region,直接使用 | |
| 172 | + if (StrUtil.isNotEmpty(config.getRegion())) { | |
| 173 | + return config.getRegion(); | |
| 174 | + } | |
| 175 | + | |
| 176 | + // 2. 尝试从 endpoint 中解析 region | |
| 177 | + String endpoint = config.getEndpoint(); | |
| 178 | + if (StrUtil.isEmpty(endpoint)) { | |
| 179 | + return "us-east-1"; | |
| 180 | + } | |
| 181 | + | |
| 182 | + // 移除协议头(http:// 或 https://) | |
| 183 | + String host = endpoint; | |
| 184 | + if (HttpUtil.isHttp(endpoint) || HttpUtil.isHttps(endpoint)) { | |
| 185 | + try { | |
| 186 | + host = URI.create(endpoint).getHost(); | |
| 187 | + } catch (Exception e) { | |
| 188 | + // 解析失败,使用默认值 | |
| 189 | + return "us-east-1"; | |
| 190 | + } | |
| 191 | + } | |
| 192 | + | |
| 193 | + if (StrUtil.isEmpty(host)) { | |
| 194 | + return "us-east-1"; | |
| 195 | + } | |
| 196 | + | |
| 197 | + // 3. AWS S3 格式:s3.us-west-2.amazonaws.com 或 s3.amazonaws.com | |
| 198 | + if (host.contains("amazonaws.com")) { | |
| 199 | + // 匹配 s3.{region}.amazonaws.com 格式 | |
| 200 | + if (host.startsWith("s3.") && host.contains(".amazonaws.com")) { | |
| 201 | + String regionPart = host.substring(3, host.indexOf(".amazonaws.com")); | |
| 202 | + if (StrUtil.isNotEmpty(regionPart) && !regionPart.equals("accelerate")) { | |
| 203 | + return regionPart; | |
| 204 | + } | |
| 205 | + } | |
| 206 | + // s3.amazonaws.com 或 s3-accelerate.amazonaws.com 使用默认值 | |
| 207 | + return "us-east-1"; | |
| 208 | + } | |
| 209 | + | |
| 210 | + // 4. 阿里云 OSS 格式:oss-cn-beijing.aliyuncs.com | |
| 211 | + if (host.contains(S3FileClientConfig.ENDPOINT_ALIYUN)) { | |
| 212 | + // 匹配 oss-{region}.aliyuncs.com 格式 | |
| 213 | + if (host.startsWith("oss-") && host.contains("." + S3FileClientConfig.ENDPOINT_ALIYUN)) { | |
| 214 | + String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_ALIYUN)); | |
| 215 | + if (StrUtil.isNotEmpty(regionPart)) { | |
| 216 | + return regionPart; | |
| 217 | + } | |
| 218 | + } | |
| 219 | + } | |
| 220 | + | |
| 221 | + // 5. 腾讯云 COS 格式:cos.ap-shanghai.myqcloud.com | |
| 222 | + if (host.contains(S3FileClientConfig.ENDPOINT_TENCENT)) { | |
| 223 | + // 匹配 cos.{region}.myqcloud.com 格式 | |
| 224 | + if (host.startsWith("cos.") && host.contains("." + S3FileClientConfig.ENDPOINT_TENCENT)) { | |
| 225 | + String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_TENCENT)); | |
| 226 | + if (StrUtil.isNotEmpty(regionPart)) { | |
| 227 | + return regionPart; | |
| 228 | + } | |
| 229 | + } | |
| 230 | + } | |
| 231 | + | |
| 232 | + // 6. 其他情况(MinIO、七牛云等)使用默认值 | |
| 233 | + return "us-east-1"; | |
| 234 | + } | |
| 235 | + | |
| 162 | 236 | } | ... | ... |
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 { |
| 82 | 82 | @NotNull(message = "是否公开访问不能为空") |
| 83 | 83 | private Boolean enablePublicAccess; |
| 84 | 84 | |
| 85 | + /** | |
| 86 | + * AWS 区域 | |
| 87 | + * 1. AWS S3:https://docs.aws.amazon.com/general/latest/gr/s3.html 例如说,us-east-1、us-west-2 | |
| 88 | + * 2. MinIO:可以填任意值,通常使用 us-east-1 | |
| 89 | + * 3. 阿里云:不需要填写,会自动识别 | |
| 90 | + * 4. 腾讯云:不需要填写,会自动识别 | |
| 91 | + * 5. 七牛云:不需要填写,会自动识别 | |
| 92 | + * 6. 华为云:不需要填写,会自动识别 | |
| 93 | + * 7. 火山云:不需要填写,会自动识别 | |
| 94 | + */ | |
| 95 | + private String region; | |
| 96 | + | |
| 85 | 97 | @SuppressWarnings("RedundantIfStatement") |
| 86 | 98 | @AssertTrue(message = "domain 不能为空") |
| 87 | 99 | @JsonIgnore | ... | ... |