首页 > 解决方案 > 使用 S3 Java SDK 上传到 GCS:`您在 Content-MD5 或 x-goog-hash 中指定的 MD5 与我们计算的不匹配`

问题描述

我正在尝试使用 AWS SDK For Java 1.x 上传到 Google Cloud Storage。我已启用互操作性模式并将其放入AWS_ACCESS_KEY_ID环境AWS_SECRET_ACCESS_KEY中。我可以列出对象,但上传对我不起作用。

我正在使用的代码是

    AmazonS3 client =
        AmazonS3ClientBuilder.standard()
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(
                    "http://storage.googleapis.com", "auto"))
            .build();

    TransferManager tm = TransferManagerBuilder.standard()
        .withS3Client(client)
        .build();
    Upload upload = tm.upload(bucketName, key, new File(filename));
    upload.waitForCompletion();

但我得到的结果是:

com.amazonaws.services.s3.model.AmazonS3Exception: The MD5 you specified in Content-MD5 or x-goog-hash did not match what we computed. (Service: Amazon S3; Status Code: 400; Error Code: BadDigest; Request ID: null; S3 Extended Request ID: null; Proxy: null), S3 Extended Request ID: null
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1819)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1403)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1372)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1145)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5437)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5384)

相同的代码适用于 S3(减去 EndpointConfiguration)

标签: google-cloud-storageaws-sdk-java

解决方案


GCS 文档说:

在 Cloud Storage XML API 中,分块传输编码和 V4 签名目前不能同时使用。一些 Amazon S3 工具默认使用分块传输编码和签名;在这种情况下,您应该禁用分块传输编码。

我找到了两种解决此错误的方法

  1. 您可以.withChunkedEncodingDisabled(true)在构建客户端时:

     AmazonS3 client =
         AmazonS3ClientBuilder.standard()
             .withChunkedEncodingDisabled(true)  // <<<<<<<
             .withEndpointConfiguration(
                 new AwsClientBuilder.EndpointConfiguration(
                     "http://storage.googleapis.com", "auto"))
             .build();
    
  2. 您可以切换到 https 端点:

     AmazonS3 client =
         AmazonS3ClientBuilder.standard()
             .withEndpointConfiguration(
                 new AwsClientBuilder.EndpointConfiguration(
                     "https://storage.googleapis.com", "auto"))
             .build();
    

推荐阅读