[英]How to upload multipart to Amazon S3 asynchronously using the java SDK
[英]Put file to Amazon S3 using multipart upload
我正在尝试通过分段上传来上传带有Amazon Java SDK的文件。 我们的想法是将upload-id传递给applet,applet将文件部分放入readonly-bucket中。 通过这种方式,我避免将AWS凭证存储在applet中。
在我的测试中,我使用boto(python)生成upload-id并将文件存储到存储桶中。 这很好用。
我的Applet从S3获得“403 Access denied”,我不知道为什么。
这是我的代码(部分来自http://docs.amazonwebservices.com/AmazonS3/latest/dev/llJavaUploadFile.html ):
AmazonS3 s3Client = new AmazonS3Client();
List<PartETag> partETags = new ArrayList<PartETag>();
long contentLength = file.length();
long partSize = Config.getInstance().getInt("part_size");
String bucketName = Config.getInstance().getString("bucket");
String keyName = "mykey";
String uploadId = getParameter("upload_id");
try {
long filePosition = 0;
for (int i = 1; filePosition < contentLength; i++) {
partSize = Math.min(partSize, (contentLength - filePosition));
// Create request to upload a part.
UploadPartRequest uploadRequest = new UploadPartRequest()
.withBucketName(bucket).withKey(keyName)
.withUploadId(uploadId).withPartNumber(i)
.withFileOffset(filePosition)
.withFile(file)
.withPartSize(partSize);
// Upload part and add response to our list.
partETags.add(s3Client.uploadPart(uploadRequest).getPartETag());
filePosition += partSize;
}
System.out.println("Completing upload");
CompleteMultipartUploadRequest compRequest = new
CompleteMultipartUploadRequest(bucket,
keyName,
uploadId,
partETags);
s3Client.completeMultipartUpload(compRequest);
} catch (Exception e) {
s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(
bucketName, keyName, uploadId));
}
在applet调试日志中,我找到了这个,然后:
INFO: Sending Request: PUT https://mybucket.s3.amazonaws.com /mykey Parameters: (uploadId: V4hwobOLQ1rYof54zRW0pfk2EfhN7B0fpMJTOpHOcmaUl8k_ejSo_znPI540.lpO.ZO.bGjh.3cx8a12ZMODfA--, partNumber: 1, ) Headers: (Content-Length: 4288546, Content-Type: application/x-www-form-urlencoded; charset=utf-8, )
24.01.2012 16:48:42 com.amazonaws.http.AmazonHttpClient handleErrorResponse
INFO: Received error response: Status Code: 403, AWS Service: null, AWS Request ID: DECF32CCFEE9EBF0, AWS Error Code: AccessDenied, AWS Error Message: Access Denied, S3 Extended Request ID: xtL1ixsGM2/vsxJ+cZRHpkPZ23SMfP8hZZjQCQnp8oWGwdS2/aGfYgomihyqaDCQ
你在代码中发现任何明显的失败吗?
谢谢,斯特凡
虽然你的用例是合理的,这确实是一个明显的尝试,但我不认为Multipart Upload API的设计允许这样做,你实际上违反了安全障碍:
上传ID仅仅是一个标识符,用于帮助Multipart Upload API将部件组装在一起(即更像是临时对象密钥)而不是专用的安全机制(见下文)。 因此,您仍然需要适当的访问凭据,但由于您正在调用构建将向Amazon S3发出匿名请求的新Amazon S3客户端的 AmazonS3Client() ,因此您的请求会相应地拒绝403 Access 。
您试图通过使用预签名URL上传对象来实现,但不幸的是,只有没有多部分功能:
如果预签名URL的创建者有权访问该对象,则预签名URL允许您访问URL中标识的对象。 也就是说,如果您收到用于上传对象的预签名URL,则只有在预签名URL的创建者具有上载该对象的必要权限时,才能上载该对象。
[...]如果您希望您的用户/客户能够上传特定对象[...],则预先签名的URL非常有用,但您不需要他们拥有AWS安全凭据或权限。 创建预签名URL时,必须提供安全凭证,指定存储桶名称和对象密钥,HTTP方法(上载对象的PUT)以及到期日期和时间。 [...]
长篇引语说明了为什么像这样的系统可能需要比“仅仅”分发上传ID更复杂的安全设计(类似于两者可能一见钟情)。
显然,人们希望能够同时使用这两种功能,但这似乎还没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.