【问题标题】:Retrofit2 error java.io.EOFException: End of input at line 1 column 1Retrofit2 错误 java.io.EOFException:第 1 行第 1 列输入结束
【发布时间】:2022-01-27 06:52:06
【问题描述】:

我使用 Retrofit2 调用了 PATCH 网络服务,但没有调用 onResponse 并且调用了 onFailure 尽管服务端运行成功完美

每当我尝试使用 fiddler 来检查服务的工作时,我发现问题是序列化服务的即将到来的响应,当使用 fiddler 时,我发现 JSON 响应没有内容,所以 Retrofit 服务假设它失败了,因为没有内容并且它无法序列化 EMPTY 内容 并给我这个错误

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

提琴手原始响应

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

【问题讨论】:

  • 如果正文为空,则返回 void
  • 我在 java 代码中将对象类型替换为 Void 类型,并且在 web 服务返回中没有更改,感谢您的提示,以便您可以发布答案以接受并标记它:) @Bhargav

标签: android web-services retrofit2


【解决方案1】:

如果正文为空,则返回 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>>

【讨论】:

  • 请改成@PATCH("alerts/{alert_id}/accept") 调用accept_invited_alerts(@Header("X-Api-Token") String api_token, @Path("alert_id" ) int alert_id); @Bhargav
  • @MinaFared 哎呀,谢谢!我忘记了它是如何工作的
  • @Bhargav,谢谢你拯救了我的一天
  • 如果你使用 RX,你应该使用 Response.class 允许空体。喜欢这里:Observable>
  • 我刚刚使用Completable作为响应类型
【解决方案2】:

您可以创建 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);               
            }
        };
    }
}

并添加到代码创建。例如:

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

我希望它可以帮助您解决问题。 谢谢!

编辑!!!

对于 kotlin 用例,您可以检查一下

class NullOnEmptyConverterFactory : Converter.Factory() {
override fun responseBodyConverter(
    type: Type,
    annotations: Array<Annotation>,
    retrofit: Retrofit
): Converter<ResponseBody, *> {
    val delegate: Converter<ResponseBody, *> =
        retrofit.nextResponseBodyConverter<Any>(this, type, annotations)
    return Converter { body -> if (body.contentLength() == 0L) null else delegate.convert(body) }
}

}

【讨论】:

  • 这为我完成了这项工作,因为我仍然想阅读潜在的错误响应正文,但在成功的情况下没有内容,只有 200,干杯
  • 这才是真正的处理方式。向作者致敬! :)
  • 谢谢!这真的很有帮助。万一有人在寻找 kotlin 等价物 gist.github.com/rajivrnair/ddaef641d85b1dc402c72ac7e1cac0b6
  • 它是否有助于解决流错误结束?
【解决方案3】:

非常感谢。

API

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

【讨论】:

    【解决方案4】:

    对我来说,在 laravel 中,我在功能完成后没有发送任何响应,只是在服务器端添加以下行有帮助。这可以适应您使用的语言。 只需从服务器端发送一些响应。

    use Response;
    
    return Response::json(array(
                'result' => 'success',
    
            ));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-15
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 2018-01-10
      • 1970-01-01
      相关资源
      最近更新 更多