Search code examples
androidlaravelretrofit2image-uploading

Unable to upload Image with Retrofit 2


I am unable to upload an image from Retrofit 2, please look at my below code

@Multipart
@POST("upload-image")
Call<UploadImageResponse> uploadFile(@Part MultipartBody.Part file, @Part("file") RequestBody name);

and the function i call performs like that,

// Uploading Image
public void uploadFile()
{
    // Map is used to multipart the file using okhttp3.RequestBody
    File file = new File(sellerActivity.mediaPath);

    // Parsing any Media type file
    RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);

    MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", file.getName(), requestBody);

    RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), file.getName());

    Call<UploadImageResponse> call = apiService.uploadFile(fileToUpload, filename);

    call.enqueue(new Callback<UploadImageResponse>() {
        @Override
        public void onResponse(Call<UploadImageResponse> call, Response<UploadImageResponse> response) {
            if (response.isSuccessful())
            {
                System.out.println("Image Url: " + response.body().getImage() + " " + response.body().getDishesName());
                System.out.println("Image Message: " + response.raw());
            }
            else
            {
                System.out.println("Image Message: " + response.raw());
            }
        }

        @Override
        public void onFailure(Call<UploadImageResponse> call, Throwable t) {
            System.out.println("onFailure: " + t);
        }
    });
}

when I use postman I do that

Postman Screenshot

I have searched and tried various methods but no success. any help will be appreciated.


Solution

  • You must have a clear understanding of multipart form data, so read this link and many others available out there.

    Answer is Change your endpoint method as given below:

    @Multipart
    @POST("upload-image")
    Call<UploadImageResponse> uploadFile(@Part MultipartBody.Part file, @Part("dishes_name") RequestBody name);
    

    You are missing to assign proper keys to each part.

    Also, change the implementation as below:

    // Uploading Image
    public void uploadFile()
    {
        // Map is used to multipart the file using okhttp3.RequestBody
        File file = new File(sellerActivity.mediaPath);
    
        // Parsing any Media type file
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
    
        MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
    
        RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), file.getName());
    
        Call<UploadImageResponse> call = apiService.uploadFile(fileToUpload, filename);
    
        call.enqueue(new Callback<UploadImageResponse>() {
            @Override
            public void onResponse(Call<UploadImageResponse> call, Response<UploadImageResponse> response) {
                if (response.isSuccessful())
                {
                    System.out.println("Image Url: " + response.body().getImage() + " " + response.body().getDishesName());
                    System.out.println("Image Message: " + response.raw());
                }
                else
                {
                    System.out.println("Image Message: " + response.raw());
                }
            }
    
            @Override
            public void onFailure(Call<UploadImageResponse> call, Throwable t) {
                System.out.println("onFailure: " + t);
            }
        });
    }
    

    The first parameter in the MultipartBody.Part.createFormData(keyName, fileName, requestBody) method is the key name of the multipart file, the second parameter is the filename, the third parameter is the request body of this part. link.

    I hope this will help you.