Ошибка Retrofit2 java.io.EOFException: конец ввода в строке 1 столбца 1

Я вызвал веб-службу PATCH с помощью Retrofit2, но onResponse не вызывается, а вызывается onFailure, несмотря на операцию служба выполняется на стороне сервера идеально

И всякий раз, когда я пытался использовать fiddler для проверки работы службы, я обнаружил, что проблема заключается в том, что сериализация поступающего ответа службы и при использовании fiddler я обнаружил, что нет содержимого ответа JSON, поэтому служба модернизации предположила, что она не удалась, потому что контента нет, и он не может сериализовать ПУСТОЙ контент и выдать мне эту ошибку

java.io.EOFException: End of input at line 1 column 1

Необработанный ответ Fiddler

HTTP/1.1 200 OK
Server: nginx/1.9.4
Date: Wed, 02 Mar 2016 09:55:55 GMT
Content-Type: application/json
Content-Length: 0
Connection: close
Status: 200 OK
X-Content-Type-Options: nosniff

Ответ Fiddler Json пуст

веб-служба в Java

Call<Object> call = TimeCapp.services.accept_invited_alerts(HomeActivity.api_token, alert_id);

call.enqueue(new Callback<Object>()
{
    @Override
    public void onResponse (Call<Object> call, Response<Object> response)
    {
        if (response.isSuccess()) {
            String x = response.body();
        }
    }
    @Override
    public void onFailure (Call<Object>call, Throwable t)
    {
        String x = t.getMessage();//java.io.EOFException: End of input at line 1 column 1
    }
}

Я попытался заменить object на String,JsonObject,emptyCalssBody.... но это не удалось

интерфейс веб-службы

@PATCH("alerts/{alert_id}/accept")
Call<Object> accept_invited_alerts(@Header("X-Api-Token") String  
api_token, @Path("alert_id") int alert_id);

person Mina Farid    schedule 02.03.2016    source источник
comment
вместо этого просто верните void, если тело пусто   -  person Bhargav    schedule 02.03.2016
comment
я заменил тип объекта на тип Void в коде Java и не изменился в возврате веб-сервиса, спасибо за подсказку, чтобы вы могли опубликовать ответ, чтобы принять и отметить его :) @Bhargav   -  person Mina Farid    schedule 02.03.2016


Ответы (3)


вместо этого просто верните void, если тело пусто

@PATCH("alerts/{alert_id}/accept") Call<Void> accept_invited_alerts(@Header("X-Api-Token") String api_token, @Path("alert_id") int alert_id);

для модернизации с помощью Rx java вы можете использовать что-то вроде этого

@PATCH("alerts/{alert_id}/accept") Observable<Response<Void>> accept_invited_alerts(@Header("X-Api-Token") String api_token, @Path("alert_id") int alert_id);

РЕДАКТИРОВАТЬ: для котлина

@PATCH("alerts/{alert_id}/accept")
fun accept_invited_alerts(@Header("X-Api-Token")  api_token: String, @Path("alert_id") alert_id: Int): Call<Unit>

и

@PATCH("alerts/{alert_id}/accept")
fun accept_invited_alerts(@Header("X-Api-Token") api_token: String, @Path("alert_id") alert_id: Int): Observable<Response<Unit>>
person Bhargav    schedule 02.03.2016
comment
пожалуйста, измените на @PATCH(alerts/{alert_id}/accept) Call‹Void›accept_invited_alerts(@Header(X-Api-Token) String api_token, @Path(alert_id) int alert_id); @Бхаргав - person Mina Farid; 02.03.2016
comment
@MinaFared ой, спасибо! Я забыл, как это работает - person Bhargav; 02.03.2016
comment
@Bhargav, спасибо, ты спас мой день - person Sadashiv; 21.12.2016
comment
Если вы используете RX, вы должны использовать Response.class, который разрешает нулевые тела. Как здесь: Observable‹Response‹Void›› - person Devnock; 12.07.2018
comment
Я только что использовал Completable в качестве типа ответа - person Albert Vila Calvo; 30.04.2019
comment
для того же в Kotlin используйте Unit вместо Void как в Observable<Response<Unit>> - person RKB; 24.05.2021

Вы можете создать NullOnEmptyConverterFactory.class :

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;


public class NullOnEmptyConverterFactory extends Converter.Factory {

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
        return new Converter<ResponseBody, Object>() {
            @Override
            public Object convert(ResponseBody body) throws IOException {
                if (body.contentLength() == 0) return null;
                return delegate.convert(body);               
            }
        };
    }
}

и добавить в код create. Например:

 UploadImageNghiemThuApi uploadService = new Retrofit.Builder()
            .baseUrl(Config.URL+"/")
            .client(okHttpClient)
            // -----add here-------
            .addConverterFactory(new NullOnEmptyConverterFactory())
            //---------------------
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(UploadImageNghiemThuApi.class);

Я надеюсь, что это может помочь вашей проблеме. Спасибо!

person Thientvse    schedule 18.05.2018
comment
Это сработало для меня, так как я все еще хочу прочитать тело потенциального ответа об ошибке, но в случае успеха контента нет, просто 200, ура - person darnmason; 14.06.2019
comment
Это реальный способ, как с этим нужно обращаться. Автору респект! :) - person rzaaeeff; 19.07.2019
comment
Благодарю вас! Это было действительно полезно. Если кто-то ищет аналог kotlin, gist.github.com/rajivrnair/ddaef641d85b1dc402c72ac7e1cac0b6 - person Rajiv; 09.09.2020
comment
Поможет ли это случайно при ошибке конца потока? - person kvaruna; 17.02.2021

Большое тебе спасибо.

Апи

@FormUrlEncoded
@POST("/rebu/insertusuario.php")
Call<Void> insertLogin(
        @Field("email") String email,
        @Field("senha") String senha,
        @Field("codCondutor") Long codCondutor
);

Класс:

Call call = service.insertLogin(login.getEmail(), login.getSenha(), login.getCodCondutor());
person Victor Fernando    schedule 22.07.2017