Multipart Download to Amazon S3 with Retrofit

I am trying to convert all my asintets and HttpPost code to use Retrofit, as far as this is good, but I am having problems loading custom files into an amazon s3 bucket. File upload consists of two parts:

  • Request api to get upload_url and amazon upload options.
  • Upload the file to the specified location with the parameters provided on the first call.

Here is an example of a list of options provided to me from the first call. According to the documentation, these values ​​may or may not be included, and the second api call should use these parameters in the order in which they were provided.

"AWSAccessKeyId": "some_id", "key": "/users/1234/files/profile_pic.jpg", "acl": "private", "Filename": "profile_pic.jpg", "Policy": "some_opaque_string", "Signature": "another_opaque_string", "Content-Type": "image/jpeg" 

To deal with dynamic content. I created a custom converter to be able to return LinkedHashMap to me in my first API call.

 public class CustomConverter implements Converter { @Override public Object fromBody(TypedInput typedInput, Type type) throws ConversionException { ... Type mapType = new TypeToken<LinkedHashMap<String, String>>(){}.getType(); return new Gson().fromJson(JSON_STRING, mapType); } 

Then in the second call api. After I have these values, I create a FormUrlEncodedTypedOutput by iterating over the HashMap and adding each element.

 FormUrlEncodedTypedOutput params = new FormUrlEncodedTypedOutput(); for (Map.Entry<String, String> entry : uploadParams.entrySet()) { params.addField(KEY, VALUE); } 

Everything that works here seems to work. I get the necessary boot options, and the ordering seems consistent. I'm a little less sure about how I set the multiplier setting for retrofitting. Then I use this inside a synchronous call to retool inside an intenservice.

 @Multipart @POST("/") Response uploadFile(@Part ("whatdoesthisdo?") FormUrlEncodedTypedOutput params, @Part("File") TypedFile file); 

This results in an Amazon error.

 "code" : "InvalidArgument" "message" : "Bucket POST must contain a field named 'key'. If it is specified, please check the order of the fields." 

I was looking for googling, and does Amazon seem to prefer the “key” meaning to be first? However, if I put the "key" before "AWSAccessKeyId", I get a 403 unauthorized error. Did I set up the setup for retrofitting correctly? If someone helped me figure this out, I would appreciate it. It took several days to convert most of my download code into a modified version, and if I lingered on this for some time.

Thanks!

+6
source share
1 answer

The solution was to use @PartMap instead of FormUrlEncodedTypedOutput.

 @Multipart @POST("/") Response uploadFile(@PartMap LinkedHashMap<String,String> params, @Part("File") TypedFile file); 
+4
source

Source: https://habr.com/ru/post/985394/


All Articles