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

Java 将文件上载到S3时,如何设置内容md5?,java,amazon-web-services,amazon-s3,Java,Amazon Web Services,Amazon S3,我试图在将文件上载到S3时设置content-MD5值。我可以看到md5哈希字符串,并将其传递到metadata.setContentMD5()中,但上传文件后,我在web控制台中看不到该值,也无法通过java代码检索该值 我开始认为我可能误解了content MD5 get/set方法的目标。它们是否用于让aws服务器验证接收到的文件内容是否与我发送的内容一致?如果是这种情况,那么我应该在上传时发送一个带有setContentMD5(my_md5)的值,但是当我稍后尝试从S3下载该对象时,我应

我试图在将文件上载到S3时设置content-MD5值。我可以看到md5哈希字符串,并将其传递到
metadata.setContentMD5()
中,但上传文件后,我在web控制台中看不到该值,也无法通过java代码检索该值

我开始认为我可能误解了content MD5 get/set方法的目标。它们是否用于让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()为下载的文件有一个值吗?

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

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

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


最后一部分可能意味着:返回null,除非您以前调用过
setContentMD5()

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

MD5仅在传输期间有意义,一旦接收并验证传输,其生命周期即停止。在服务器端持久化它毫无用处


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

是的,在玩了一点之后,我想它很清楚,就像你描述的那样。我猜我最初认为,如果它们表示文件内容的相同MD5哈希,那么传入的MD5字符串将与ETag相同,而事实并非如此,即使它们都基于相同的源字节。