Double_M
Double_M

Reputation: 311

Retrofit2 - Upload image to server give an Internal Server Error as response in android studio

I am trying to send image files from my android app to a back end server. On Postman, images are sent and response code:200 is received.enter image description here

However, trying to send images from my android app using retrofit, I keep receiving response code:500 Internal Server Error. Here is my code:

public interface RetrofitInterface {
    @Multipart
    @POST("uploads/addImage")
    Call<ResponseBody> uploadImage(@Part MultipartBody.Part image);
}

The NetworkClient

public class NetworkClient {
    private static Retrofit retrofit;

    public static Retrofit getRetrofit(){
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS).build();
        if(retrofit == null){
            String BASE_URL = "https://addimage.herokuapp.com/";
            retrofit = new Retrofit.Builder().baseUrl(BASE_URL).
                    addConverterFactory(GsonConverterFactory.create()).client(okHttpClient).build();
        }
        return retrofit;
    }
}

And then the call

private void uploadImage(Uri imageUri){

        File file = new File(imageUri.toString());

        RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
        MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);

        Retrofit retrofit = NetworkClient.getRetrofit();
        RetrofitInterface retrofitInterface = retrofit.create(RetrofitInterface.class);

        Call<ResponseBody> call = retrofitInterface.uploadImage(body);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if(response.isSuccessful()){
                    Log.d("UploadImage", "Yeepee!!! = "+response.message());
                }else Log.d("UploadImage", "Response failure = "+response.message());
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                if (t instanceof SocketTimeoutException) {
                    // "Connection Timeout";
                    Log.e("UploadImage", "Connection Timeout");
                } else if (t instanceof IOException) {
                    // "Timeout";
                    Log.e("UploadImage", "Timeout");
                } else {
                    //Call was cancelled by user
                    if(call.isCanceled()) {
                        Log.e("UploadImage", "Call was cancelled forcefully");
                    } else {
                        //Generic error handling
                        Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
                    }
                }
            }
        });
}

I am not sure if it's a server error since images upload successfully from Postman. I am very confused and I am not sure what I am doing wrong.

Upvotes: 2

Views: 2840

Answers (3)

Double_M
Double_M

Reputation: 311

Thank you all for your responses. I have been able to resolve and it turned out to be a conflict between my request body and what the server was expecting.

For my case, I was sending a different mime-type(a .jpg), where the server developer made the server look for .jpeg and .png.

This was how I got to see the error and resolve the conflict.

Call<ResponseBody> call = retrofitInterface.uploadImage(body);
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
      if(response.isSuccessful()){
                    Log.d("UploadImage", "Yeepee!!! = "+response.message());
                }else {
                    Log.d("UploadImage", "Response failure = "+response.message());
                    try {
                        Log.d("UploadImage", "Response failure = "+response.errorBody().string());
                    } catch (IOException e) {
                        Log.d("UploadImage", "IOException = "+e.getMessage());
                    }
                }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
                if (t instanceof SocketTimeoutException) {
                    // "Connection Timeout";
                    Log.e("UploadImage", "Connection Timeout");
                } else if (t instanceof IOException) {
                    // "Timeout";
                    Log.e("UploadImage", "Timeout");
                } else {
                    //Call was cancelled by user
                    if(call.isCanceled()) {
                        Log.e("UploadImage", "Call was cancelled forcefully");
                    } else {
                        //Generic error handling
                        Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
                    }
                }
            }
        });

The response.errorBody().string() got the error message from the server and I was able to resolve the conflict.

Upvotes: 0

Dulanga
Dulanga

Reputation: 931

According to your Postmen screen shot there is no key for image file can you try like below

remove this line

    MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);

And add this one

MultipartBody.Part body = MultipartBody.Part.createFormData("", "image.jpg", requestBody);

Upvotes: 1

Soumik Bhattacharjee
Soumik Bhattacharjee

Reputation: 945

Generally 500 Internal Server error means there is something wrong in the server, but if the Postman is giving 200 that means the server part is OK, there's something wrong in your code.

try changing this line

File file = new File(imageUri.toString()); 

to this

File file = new File(imageUri.path);

And also make sure that the key name you used is same as the response key name

Upvotes: 0

Related Questions