wake-up-neo.com

OKHttp löst eine ungültige Statusausnahme aus, wenn ich versuche, die Netzwerkantwort zu protokollieren

Ich habe den folgenden Interceptor auf meinem OkHttp-Client installiert:

httpClient.addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());
        Log.d("Response", response.body().string());
        return response;
    }
    });

Mit Retrofit 2 wird jedoch nicht Nice gespielt. Es scheint, dass Sie den Stream nur einmal aus der Antwort lesen können. Dies ist möglicherweise die Ursache der Ausnahme. Ich denke, Retrofit versucht, den Stream zu analysieren, den das Protokoll bereits analysiert hat. Wie bekomme ich dann die Antwort? Ich versuche gerade, eine sehr unangenehme und merkwürdige missgebildete Json-Ausnahme zu debuggen.

Dies ist die Ausnahme-Stack-Ablaufverfolgung:

07 - 28 10: 58: 21.575 22401 - 22529 / REDACTED E / AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
    Process: REDACTED, PID: 22401
    Java.lang.IllegalStateException: closed
    at okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.Java: 378)
    at okio.Buffer.writeAll(Buffer.Java: 956)
    at okio.RealBufferedSource.readByteArray(RealBufferedSource.Java: 92)
    at okhttp3.ResponseBody.bytes(ResponseBody.Java: 83)
    at okhttp3.ResponseBody.string(ResponseBody.Java: 109)
    at REDACTED.ServiceGenerator$2.intercept(ServiceGenerator.Java: 90)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.Java: 187)
    at REDACTED.ServiceGenerator$2.intercept(ServiceGenerator.Java: 89)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.Java: 187)
    at REDACTED.ServiceGenerator$2.intercept(ServiceGenerator.Java: 89)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.Java: 187)
    at REDACTED.ServiceGenerator$2.intercept(ServiceGenerator.Java: 89)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.Java: 187)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.Java: 160)
    at okhttp3.RealCall.access$100(RealCall.Java: 30)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.Java: 127)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.Java: 32)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java: 1112)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java: 587)
    at Java.lang.Thread.run(Thread.Java: 841)

Ich sehe, dass es mehrere Abfangjäger im Stack gibt, aber ich füge immer nur den einen explizit hinzu. Dies ist der On, der die Ausnahme auslöst.

Sie verbrauchen den Antworttext im Abfangjäger. Sie möchten also eine neue Antwort erstellen:

@Override public Response intercept(Chain chain) throws IOException {
  Response response = chain.proceed(chain.request());
  ResponseBody body = response.body();
  String bodyString = body.string();
  MediaType contentType = body.contentType();
  Log.d("Response", bodyString);
  return response.newBuilder().body(ResponseBody.create(contentType, bodyString)).build();
}

Sie können auch den Protokollierungs-Interceptor im Repo von OkHttp überprüfen: https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor

26
Eric Cochran

Rufen Sie den Antworttext nicht mehr als einmal auf, da er als Stream gelesen und nicht im Speicher gespeichert wird.

Vielleicht rufen Sie response.body (). String () mehr als einmal an, da der Antworttextkörper sehr groß sein kann. OkHttp speichert sie also nicht im Arbeitsspeicher, sondern liest ihn bei Bedarf als Stream aus dem Netzwerk.

Wenn Sie body als Zeichenfolge lesen (), lädt OkHttp den Antworttext herunter und gibt ihn an Sie zurück, ohne den Bezug auf die Zeichenfolge beizubehalten. Er kann nicht zweimal ohne neue Anforderung heruntergeladen werden.

https://github.com/square/okhttp/issues/1240

15
user4981235

Ich habe diese Ausnahme auch erhalten, weil ich versuche, den Antworttext 2X zu konvertieren. Zuerst protokollierte ich die response.body (). String () & dann übergab ich dasselbe einer Methode. , Die die Ausnahme verursachte. Prüfen Sie, ob der Antworttext mehr als einmal in eine Zeichenfolge umgewandelt wird.

3
Gaurav

Der Fehler ist seltsam, aber das erste Problem, das ich sehe, ist, dass Sie OKHTTP3 verwenden und versuchen, dem bereits erstellten Client einen Builder hinzuzufügen.

Der OkHttpClient ist immutable jetzt und Sie müssen die Interceptors direkt der OkHttpClient.Builder hinzufügen, indem Sie die Methode addInterceptor im Builder aufrufen .

Weitere Informationen zur Vorgehensweise finden Sie unter Github Ausgabe . Ich denke, das sollte dein Problem lösen.

0
Aashrai Ravooru

Der Antworttext kann sehr umfangreich sein. OkHttp speichert ihn nicht im Speicher, sondern liest ihn bei Bedarf als Stream aus dem Netzwerk.

Wenn Sie body als Zeichenfolge lesen (), lädt OkHttp den Antworttext herunter und sendet ihn an Sie zurück, ohne den Verweis auf die Zeichenfolge beizubehalten. Ohne neue Anforderung kann er nicht zweimal heruntergeladen werden.

0
Dhananjay Kumar