将文件上传到S3时,如何设置内容md5?

时间:2016-02-14 21:40:49

标签: java amazon-web-services amazon-s3

我在尝试将文件上传到S3时设置内容-MD5值。我可以看到md5哈希字符串并将其传递到metadata.setContentMD5()但是在上传文件后,我无法在Web控制台中看到此值,并且无法通过Java代码检索它。

我开始认为我可能误解了内容MD5获取/设置方法的目标。他们是否习惯让aws服务器验证收到的文件内容是否与我发送的内容一致?如果是这种情况,那么我应该在上传时发送setContentMD5(my_md5)的值,但是当我稍后尝试从S3下载该对象时,我应该只将getETag()的值与我计算的md5十六进制字符串进行比较?

我在尝试设置此md5值时做错了吗?

String access_key = "myaccesskey";
String secret_key = "mysecretkey";
String bucket_name = "mybucketname";
String destination_key = "md5_test.txt";
String file_path = "C:\\my-text-file.txt";

BasicAWSCredentials creds = new BasicAWSCredentials(access_key, secret_key);
AmazonS3Client client = new AmazonS3Client(creds);
client.setRegion(RegionUtils.getRegion("us-east-1"));

File file = new File(file_path);

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("text/plain");
metadata.setContentLength(file.length());

FileInputStream fis = new FileInputStream(file);
byte[] content_bytes = IOUtils.toByteArray(fis);
String md5 = new String(Base64.encodeBase64(DigestUtils.md5(content_bytes)));
metadata.setContentMD5(md5);

PutObjectRequest req = new PutObjectRequest(bucket_name, destination_key, file).withMetadata(metadata);
PutObjectResult result = client.putObject(req);

GetObjectMetadataRequest mreq = new GetObjectMetadataRequest(bucket_name, destination_key);
ObjectMetadata retrieved_metadata = client.getObjectMetadata(mreq);

// I think I expected getContentMD5 below to show the string I passed in
// during the upload, but the below prints "md5:null"
System.out.println("md5:" + retrieved_metadata.getContentMD5());

我是否错误地计算了MD5字符串?如果我传入一个随机字符串,我会收到一条错误消息,所以看起来S3很满意我通过上面的代码发送的内容。如果MD5字符串正确,为什么以后在使用client.getContentMD5()方法时无法检索它?我知道ETag应该是MD5十六进制字符串,我也可以为我上传的文件计算(并得到S3计算的相同字符串),所以我不应该期望getContentMD5()有下载文件的值?

2 个答案:

答案 0 :(得分:3)

我认为你是对的:getContentMD5()只是setContentMD5() 1的相应吸气剂。它告诉您请求的被叫方认为MD5哈希是什么。如果您想知道AWS认为散列是什么,您应该使用ETag。

  

getContentMD5

     

此字段表示在呼叫方侧计算的对象内容的base64编码的128位MD5摘要摘要。 ETag元数据字段表示由Amazon S3计算的十六进制编码的128位MD5摘要。

     

返回:关联对象的内容的base64编码MD5哈希。 如果尚未设置内容的MD5哈希值,则返回null。

最后一部分可能意味着:除非您之前已调用setContentMD5()

,否则返回null

答案 1 :(得分:2)

您不需要传递MD5字符串,但如果提供,则亚马逊将使用它来验证传输并确保其收到的内容未损坏。

MD5仅在传输过程中有意义,并且一旦接收和验证传输,其生命周期就会停止。将其保留在服务器端是没有用的。

getter仅用于完成API,因此您可以使用setter检查之前的操作。