java - 为什么 putObject 在使用 PutObjectRequest 时会抛出 AmazonS3Exception,但在没有 PutObjectRequest 的情况下工作正常?
问题描述
我正在编写一个采用 3 个字符串参数的 Java 方法:bucketName、objectKey、objectContent。然后该方法将对象放入桶中。以下代码可以正常工作。
AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(REGION).build();
s3.putObject(bucketName, objectKey, content);
现在我想为对象设置一个内容类型,因为我将使用该方法来存储例如“text/plain”或“text/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 前面使用 CloudFront,然后在我的域中使用 Route 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/*"
]
}
}
}
]
}
解决方案
有 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);
推荐阅读
- apache-kafka - 如何在 Ksqldb 中使用标量函数条目
- python - 如何使用 args 在 python 脚本中运行多个脚本
- r - 错误:列“Fecha”无法从 POSIXct、POSIXt 转换为字符(在 R 中)
- mysql - 我如何结合两列来过滤在两者之间使用?
- java - 需要从 Mono 中提取数据
- asp.net-web-api - 对 .NET WebApi HttpBinding 的错误请求进行故障排除
- include - 使用 vcpkg 的 PCL 库设置似乎缺少包含文件(尤其是 pcl/可视化)
- python - 如何将在 Flask 服务器上创建的 PIL Image 下载到我的桌面。Image.save() 仅将其保存到服务器。无法通过 URL 访问图像
- java - 使用 Calendar.HOUR_OF_DAY 的条件语句
- ios - Xamarin 应用程序能否确定它在 iOS 14 上是否具有 LAN 访问权限?