如何使用AWS S3 Java v2 SDK对接Minio兼容存储?遇未知主机异常
解决AWS SDK v2 S3Client对接Minio的UnknownHostException问题
问题原因
你的代码抛出UnknownHostException是因为AWS SDK v2默认采用虚拟主机样式请求(把bucket名称拼在endpoint主机名前,格式为bucket.endpoint-host),而Minio默认使用路径样式请求(格式为endpoint-host/bucket)。SDK自动将请求地址修改为backend.localhost,但这个主机名不存在,导致解析失败。
解决方案
需要显式配置S3Client使用路径样式访问,具体操作如下:
- 在S3Client构建器中添加
serviceConfiguration,启用路径样式访问 - 区域配置填写任意AWS SDK认可的有效值即可(Minio不依赖该配置,但SDK要求必填)
修正后的完整代码
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.S3Configuration; import java.net.URI; import java.net.URISyntaxException; public class MinioS3ClientFactory { public static S3Client createMinioS3Client(String accessKey, String secretKey, String endpoint) throws URISyntaxException { AwsCredentialsProvider credentialsProvider = () -> AwsBasicCredentials.create(accessKey, secretKey); S3Configuration s3Config = S3Configuration.builder() .pathStyleAccessEnabled(true) // 关键配置:启用路径样式访问 .build(); return S3Client.builder() .region(Region.of("us-east-1")) // 填写任意标准区域值即可 .endpointOverride(new URI(endpoint)) .credentialsProvider(credentialsProvider) .serviceConfiguration(s3Config) .build(); } } // 调用示例 public class Main { public static void main(String[] args) throws URISyntaxException { S3Client s3Client = MinioS3ClientFactory.createMinioS3Client("your-access-key", "your-secret-key", "http://localhost:9000"); s3Client.listObjects(request -> request.bucket("backend")); } }
额外说明
- 区域参数优先使用AWS标准区域字符串(如
us-east-1),自定义的minio虽能通过初始化,但标准值可避免潜在兼容性问题 - 若你的Minio实例已配置虚拟主机样式支持(如绑定自定义域名),则无需启用路径样式,但默认Minio不开启该配置
内容的提问来源于stack exchange,提问作者Andy Zhang
相关产品推荐
相关产品推荐

