Retrofit2 204 No Content 有内容异常

Retrofit2 204 No Content has content exception

我从服务器获得空 json(“{}”)作为代码 204 的删除响应。

okhttp3.internal.http.HttpEngine class 中有一个烦人的东西被抛出:

  if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
    throw new ProtocolException(
        "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
  }

如果您尝试 return headers 中没有内容(服务器端)的内容仍然 Content-Length 大于 0;

任何非服务器端的想法如何解决这个问题?

您可以在拦截器中捕获 ProtocolException,在占位符 204 Response 中捕获 return。使用这种方法的注意事项 - 1) 您可能最终会陷入其他协议错误(重定向过多等)。如果这是一个问题,您可以将 e.getMessage() 与 okhttp 的异常消息进行比较,如果不匹配则重新抛出异常。 2) 你仍然无法访问原始回复,所以如果你运气不好,如果你需要检查 returned headers.

中的任何一个
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addNetworkInterceptor(new Interceptor() {
  @Override
  public Response intercept(Chain chain) throws IOException {
      Response response;
      try {
        response = chain.proceed(chain.request());
      } catch (ProtocolException e) {
        response = new Response.Builder()
            .request(chain.request())
            .code(204)
            .protocol(Protocol.HTTP_1_1)
            .build();
      }
    return response;
  }
});

如果使用方式稍有不同,就可以避免这种情况。而不是:

@DELETE("vehicles/{id}/")
Observable<Response<BaseResponse>> deleteVehicle(@Header("Authorization") String token, @Path("id") Long vehicleId);

我使用:

@HTTP(method = "DELETE", path = "vehicles/{id}/", hasBody = true)
Observable<Response<BaseResponse>> deleteVehicle(@Header("Authorization") String token, @Path("id") Long vehicleId);