AWS S3 Rest API with Android Retrofit V2 library, uploaded image is damaged

后端 未结 6 1565
生来不讨喜
生来不讨喜 2020-12-03 08:57

I\'m trying upload a Image from my Android APP to Amazon AWS S3 and I need use AWS Restful API.

I\'m using Retrofit 2

相关标签:
6条回答
  • 2020-12-03 09:34

    You are sending a multipart payload, but forcing the Content-type to be image/jpeg. Your jpg is corrupt because S3 probably saved the multipart headers into your jpg file since you told it the whole message was a JPG. Since you do not actually have multiple parts to send, you can drop the Multipart annotation and use Body instead of Part for your RequestBody

    public interface AwsS3 {
    
        @PUT("/{Key}")
        Call<String> upload(@Path("Key") String Key,
                    @Header("Content-Length") long length,
                    @Header("Accept") String accept,
                    @Header("Host") String host,
                    @Header("Date") String date,
                    @Header("Content-type") String contentType,
                    @Header("Authorization") String authorization,
                    @Body RequestBody body);
    }
    

    You should also be able to remove explicitly setting the Content-type and Content-length headers.

    0 讨论(0)
  • 2020-12-03 09:34

    You can use retrofit 2 to upload the image/file

    @Multipart
    @POST("/api/attachment")
    Call<JsonPrimitive> addAttachment(@Part MultipartBody.Part imageFile);
    

    Now to make the call:

     RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part imageFileBody = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
    

    Note : Make sure you are using retrofit2 as for some reason I was unable to upload image using retrofit1 library.

    0 讨论(0)
  • 2020-12-03 09:36

    I have used Retrofit 2 resolve and I use Body instead of Part for your RequestBody in interface

    @PUT("")
    Call<String> nameAPI(@Url String url, @Body RequestBody body);
    

    and java code

    // Prepare image file
    File file = new File(pathImg);
    RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), file);
    
    Call<String> call = SingletonApiServiceS3.getInstance().getService().nameAPI(
            path,
           requestBody
    );
    call.enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, final Response<String> response) {
    
            if (response.isSuccessful()) {
                // Your handling
            } else {
                // Your handling
           }
       }
    
       @Override
       public void onFailure(Call<String> call, Throwable t) {
           Toast.makeText(getContext(), "onFailure : "+t.getMessage().toString(),Toast.LENGTH_SHORT).show();
       }
    });
    
    0 讨论(0)
  • 2020-12-03 09:42
    RequestBody avatarBody = RequestBody.create(MediaType.parse("image"),file);
    MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), avatarBody);
    
    
    @Multipart
    @POST(url)
    Call<ResponseBody> uploadImageAmazon(
                @Part MultipartBody.Part filePart);
    

    I had same experience, and solved it by https://github.com/square/retrofit/issues/2424 this solution

    0 讨论(0)
  • 2020-12-03 09:42

    I haven't used Retrofit 2, just Retrofit 1, so YMMV, but I believe that the typical way to do what you're trying to do is to use TypedFile where you are attempting to use RequestBody.

    I'm guessing that Retrofit uses RequestBody internally.

    You would create the TypedFile something like:

    TypedFile typedFile = new TypedFile("multipart/form-data", new File("path/to/your/file"));
    

    and your interface would be:

       @Multipart
        @PUT("/{Key}")
        Call<String> upload(@Path("Key") String Key,
                    @Header("Content-Length") long length,
                    @Header("Accept") String accept,
                    @Header("Host") String host,
                    @Header("Date") String date,
                    @Header("Content-type") String contentType,
                    @Header("Authorization") String authorization,
                    @Part("Body") TypedFile body);
    }
    

    There's a decent example at https://futurestud.io/blog/retrofit-how-to-upload-files/

    0 讨论(0)
  • 2020-12-03 09:45

    I have the same problem, and as I use Fiddler checked the HTTP request content, I found retrofit 2.0.0 beta1 has a different with 1.9.0.

    In my problem, the different of HTTP request content prevent server get the correct data.

    In order to make a same HTTP request content, i do next steps using retrofit 2.0.0 deta1.


    In the retrofit service, add a form-data header for the http request;

    @Headers("Content-Type: multipart/form-data;boundary=95416089-b2fd-4eab-9a14-166bb9c5788b")
    

    int retrofit 2.0.0 deta1, the header using @Multipart will get a data like this:

    Content-Type: multipart/mixed

    as the deafult value is mixed, and has no boundary title.


    Do not using @Multipart to upload file, just using @Body RequestBody

    if you using @Multipart to request Server, you have to pass param(file) through

    @Part(key), then a new problem you will get. May be retrofit 2.0.0beta1 has a BUG ..., @Multipart generate a bad http request compile with 1.9.0.


    When you call the method, you need pass MultipartRequestBody to @Body RequestBody

    Using MultipartBuilder to create a MultipartRequestBody, when you new MultipartBuilder, call this consturt:

    new MultipartBuilder("95416089-b2fd-4eab-9a14-166bb9c5788b")
    

    the param is you set int @headers(boundary=)

    builder.addFormDataPart(String name, String filename, RequestBody value)
    

    This method will help form a data like below int HTTP request content:

    Content-Disposition: form-data; name="imgFile"; filename="IMG_20150911_113029.jpg" Content-Type: image/jpg Content-Length: 1179469

    RequestBody value is what you has generate in your code.

    I just resolve this problem temporary.

    Hope can help you!

    0 讨论(0)
提交回复
热议问题