【问题标题】:How can I set the content md5 when I upload a file to S3?将文件上传到 S3 时如何设置内容 md5?
【发布时间】:2016-02-14 21:40:48
【问题描述】:

我在将文件上传到 S3 时尝试设置 content-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() 有下载文件的值?

【问题讨论】:

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


    【解决方案1】:

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

    getContentMD5

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

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

    最后一部分大概意思是:返回 null 除非你之前调用过setContentMD5()

    【讨论】:

    • 是的,在玩了一会儿之后,我认为它显然如您所描述的那样。我想我最初认为如果它们旨在表示文件内容的相同 MD5 哈希,那么您传入的 MD5 字符串将与 ETag 相同,但事实并非如此,即使它们都基于相同的源字节。
    【解决方案2】:

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

    MD5 仅在传输过程中才有意义,一旦传输被接收和验证,它的生命周期就会停止。在服务器端持久化它没有任何意义。

    getter 只是为了使 API 完整,因此您可以检查您之前使用 setter 所做的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 2014-11-05
      • 2017-05-25
      • 2017-03-09
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      相关资源
      最近更新 更多