Retrofit2 - загрузка изображения на сервер дает внутреннюю ошибку сервера в качестве ответа в android studio - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь отправить файлы изображений из моего приложения android на внутренний сервер. На Почтальоне изображения отправляются, и код ответа: 200. enter image description here

Однако, пытаясь отправить изображения из моего приложения android с помощью модернизации, я продолжаю получать код ответа: внутренняя ошибка сервера 500. Вот мой код:

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

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;
    }
}

А затем вызов

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());
                    }
                }
            }
        });
}

Я не уверен, что это ошибка сервера с момента загрузки изображений успешно от Почтальона. Я очень смущен и не уверен, что делаю неправильно.

Ответы [ 3 ]

0 голосов
/ 28 января 2020

В соответствии с вашим снимком экрана Почтальона, нет ключа для файла изображения, вы можете попробовать, как показано ниже

удалить эту строку

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

И добавить эту

MultipartBody.Part body = MultipartBody.Part.createFormData("", "image.jpg", requestBody);
0 голосов
/ 28 января 2020

Спасибо всем за ваши ответы. Я смог решить, и это оказалось конфликтом между моим телом запроса и тем, что ожидал сервер.

Для моего случая я отправлял другой тип mime (a .jpg), где разработчик сервера заставил сервер искать .jpeg и .png.

Так я смог увидеть ошибку и разрешить конфликт.

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());
                    }
                }
            }
        });

response.errorBody().string() получил сообщение об ошибке с сервера, и мне удалось разрешить конфликт.

0 голосов
/ 28 января 2020

Обычно 500 Internal Server error означает, что что-то не так на сервере, но если почтальон дает 200, что означает, что с серверной частью все в порядке, в вашем коде что-то не так.

попробуйте изменить эту строку

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

к этому

File file = new File(imageUri.path);

А также убедитесь, что использованное вами имя ключа совпадает с именем ключа ответа

...