So implementieren Sie eine benutzerdefinierte Fehlerbehandlung mit retroift2
Ich rufe die API mit dem grundlegenden Nachrüstobjekt an Call
:
public interface dataApi {
@GET("animal/cats")
Call<AllAnimals> getAllData(
@Query("api_key") String apiKey
);
}
Und ich kann die Antwort in meinem Ansichtsmodell folgendermaßen erhalten:
call.enqueue(new Callback<AllAnimals>() {
@Override
public void onResponse(Call<AllAnimals> call, Response<AllAnimals> response) {
animals.setValue(response.body());
}
@Override
public void onFailure(Call<AllAnimals> call, Throwable t) {
Log.i(TAG, "onFailure: " + t);
}
});
Hier ist nichts Besonderes.
Ich habe mehrere Probleme mit diesem Ansatz
ZUERST - Wenn ich zum Beispiel den falschen API-Schlüssel gebe, sollte die Antwort mir eine Antwort mit dem Code des Problems geben, stattdessen erhalte ich nur den Nullkörper.
ZWEITENS Ich plane mehr API-Aufrufe und es ist eine riesige Code-Duplizierung, um Fehler bei jedem Anruf zu behandeln, den ich geschrieben habe.
Wie kann ich eine benutzerdefinierte Fehlerbehandlung für diese Situation implementieren, die auch für andere Aufrufe gilt?
Ich denke, Sie können okhttp Interceptor verwenden und sich als ResponseBody-Konverter definieren, um Ihr Problem zu beheben.
- Fangen Sie zunächst Ihre interessierte Anfrage und Antwort ab.
- Überprüfen Sie zweitens die Antwort. Wenn die Antwort fehlschlägt, ändern Sie den Antworttext in leer。
Definieren Sie einen einfachen Abfangjäger
Interceptor interceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String url = request.url().toString();
System.out.println(request.url());
okhttp3.Response response = chain.proceed(request);
if (!response.isSuccessful() && url.contains("animal/cats")) {
// request failed begin to modify response body
response = response.newBuilder()
.body(ResponseBody.create(MediaType.parse("application/json"), new byte[] {}))
.build();
}
return response;
}
};
Definieren Sie den Self ResponseBody-Konverter
Der meiste Code von com.squareup.retrofit2: converter-jackson wir fügen nur zwei Zeilen hinzu:
final class JacksonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final ObjectReader adapter;
JacksonResponseBodyConverter(ObjectReader adapter) {
this.adapter = adapter;
}
@Override public T convert(ResponseBody value) throws IOException {
try {
if (value.contentLength() == 0) {
return null;
}
return adapter.readValue(value.charStream());
} finally {
value.close();
}
}
}
Der folgende Code wird hinzugefügt:
if (value.contentLength() == 0) {
return null;
}