当前位置: 首页 > 知识库问答 >
问题:

为什么使用PutObjectRequest时putObject会抛出AmazonS3Exception,而不使用PutObjectRequest时运行良好?

於彬
2023-03-14

我正在编写一个Java方法,它接受3个字符串参数:桶名、对象键、对象内容。然后,该方法将对象放入桶中。下面的代码没有问题。

AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(REGION).build();
s3.putObject(bucketName, objectKey, content);

现在我想为对象设置内容类型,因为我将使用该方法存储例如“文本/纯文本”或“文本/xml”文件。所以我使用以下代码。

    AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(REGION).build();
    byte[] fileContentBytes = content.getBytes(StandardCharsets.UTF_8);
    InputStream fileInputStream = new ByteArrayInputStream(fileContentBytes);
    ObjectMetadata metaData = new ObjectMetadata();
    metaData.setContentType(contentType);
    metaData.setContentLength(fileContentBytes.length);
    PutObjectRequest putObjReq = new PutObjectRequest(bucketName, objectKey, content);
    putObjReq.setMetadata(metaData);
    s3.putObject(putObjReq);

当我运行此代码时,我会得到一个异常,如下所示。为什么?

com.amazonaws.services.s3.model.AmazonS3Exception: The website redirect location must have a prefix of 'http://' or 'https://' or '/'. (Service: Amazon S3; Status Code: 400; Error Code: InvalidRedirectLocation; Request ID: F8032DFF52EBF6F2; S3 Extended Request ID: vZX1/oTjeWU0Fok6twiyB5mEi2d0GDXYWT+akeETrapXo9CUbG+DgcabAaiFVlGXOu072vGghD4=), S3 Extended Request ID: vZX1/oTjeWU0Fok6twiyB5mEi2d0GDXYWT+akeETrapXo9CUbG+DgcabAaiFVlGXOu072vGghD4=
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1712)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1367)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1113)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:770)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:744)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:726)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:686)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:668)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:532)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:512)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4926)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4872)
    at com.amazonaws.services.s3.AmazonS3Client.access$300(AmazonS3Client.java:390)
    at com.amazonaws.services.s3.AmazonS3Client$PutObjectStrategy.invokeServiceCall(AmazonS3Client.java:5806)
    at com.amazonaws.services.s3.AmazonS3Client.uploadObject(AmazonS3Client.java:1794)
    at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1754)
    at util.DataUtils.saveContentToS3(DataUtils.java:155)
    at builder.SEOGenerator.main(SEOGenerator.java:53)

我应该注意,我使用这个S3存储桶来托管一个静态网站。我在S3前面使用Cloud前,然后在我的域中使用Road 53。我的S3存储桶策略如下。

{
    "Version": "2012-10-17",
    "Id": "http referer policy - my-domain.com",
    "Statement": [
        {
            "Sid": "Allow get requests originating from my domain",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-s3-bucket/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": [
                        "http://www.my-domain.com/*",
                        "http://my-domain.com/*",
                        "https://www.my-domain.com/*",
                        "https://my-domain.com/*"
                    ]
                }
            }
        }
    ]
}

共有1个答案

卢树
2023-03-14

有 3 种不同的方法可以调用 PutObjectRequest 构造函数。您正在使用这个:

PutObjectRequest(String bucketName, String key, String redirectLocation)

因此,您的“内容”被视为重定向位置,因此出现了错误。

我认为你的意图是用这个来代替:

PutObjectRequest(String bucketName, String key, InputStream input, ObjectMetadata metadata)

这意味着你必须做一些事情,比如:

AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(REGION).build();
byte[] fileContentBytes = content.getBytes(StandardCharsets.UTF_8);
InputStream in = new ByteArrayInputStream(fileContentBytes);
ObjectMetadata metaData = new ObjectMetadata();
metaData.setContentType(contentType);
metaData.setContentLength(fileContentBytes.length);
PutObjectRequest putObjReq = new PutObjectRequest(bucketName, objectKey, in, metaData);
s3.putObject(putObjReq);
 类似资料:
  • 问题内容: 最近,我接受了公司的采访,他们给了我一个编码问题。我得到了与纸牌有关的程序,其中一种方法是将纸牌洗牌。因此,我将该程序编写为: 在上面的代码中,我引发了我最怀疑的 IllegalArgumentException 。在什么情况下实际上应该抛出运行时异常?我们是否应该实际抛出运行时异常? 谢谢 问题答案: 我们是否应该实际抛出运行时异常? 是的,我们应该。运行时异常有特定的用途-它们发出

  • 我想在RxJava中实现一个下载一些文件的处理队列。我想下载的文件数量可能高达100个左右。 一切都是在Android上使用RxJava 1.1.1开发的 我做错了什么?

  • 问题内容: 在下面的代码中,为什么我需要导入但可以不导入就可以使用? 问题答案: 为了方便起见,Java编译器会为每个源文件自动导入两个完整的软件包: java.lang包和 当前包(当前文件的包)。 请参考 oracle.com了解更多信息(http://docs.oracle.com/javase/tutorial/java/package/usepkgs.html)

  • 我尝试对args()使用AspectJ pointcut,但在springboot和tomcat一起运行时,它会产生NullPointException。

  • 问题内容: 这是原始代码 这里私有的int x,y不是最终值是很好的,因为构造函数中的set方法会在调用get时在关系发生之前发生,因为它们使用相同的锁。 现在,这里是修改后的版本和主要方法,由于在set方法中删除了synced关键字,因此我希望在运行它后再抛出AssertionError。如果有人指出它不是线程安全的,那我就将构造函数私有化为唯一的调用者,这不是我关注的重点。 无论如何,我现在已