wake-up-neo.com

Retrofit - Antworten global abfangen

Ich möchte alle von der Retrofit-Engine erhaltenen Antworten abfangen und nach HTTP-Fehlercode suchen, z. B. Fehler 403.

Ich weiß, dass ich den Rückruf (RetrofitError-Fehler) für jede Anforderung verwenden und nach 403 suchen kann, aber ich möchte die Antwort global umschließen.

Ich kann sehen, dass das Abfangen von Anfragen möglich ist, aber ich sehe keine ähnliche Antwortmöglichkeit.

Irgendwelche Vorschläge?

24
aviran

Ich konnte das erreichen, indem ich dem OkHttpClient, den das Retrofit verwendet, einen Interceptor hinzufügt.

Retrofix 2.x:

   OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
   clientBuilder.
            addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                   Request request = chain.request();
                   Response response = chain.proceed(request);
                   if (response.code() == 403) {
                         handleForbiddenResponse();
                   }
                   return response;
                }
            });


    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(API_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(clientBuilder.build();)
            .build();

Nachrüstung 1.x:

public class ForbiddenInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        if (response.code() == 403) {
             handleForbiddenResponse();
        }
        return response;
    }
}



OkHttpClient okHttpClient = Utils.createUnsafeOkHttpClient();
okHttpClient.interceptors().add(new ForbiddenInterceptor());

RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder()
        .setEndpoint(API_BASE_URL)
        .setClient(new OkClient(okHttpClient));
61
aviran
OkHttpClient okHttpClient = new OkHttpClient.Builder()  
    .addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            okhttp3.Response response = chain.proceed(request);

            // todo deal with the issues the way you need to
            if (response.code() == 500) {
                startActivity(
                        new Intent(
                                ErrorHandlingActivity.this,
                                ServerIsBrokenActivity.class
                        )
                );

                return response;
            }

            return response;
        }
    })
    .build();

Retrofit.Builder builder = new Retrofit.Builder()  
        .baseUrl("http://your_url")
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create());

Retrofit retrofit = builder.build(); 

Wie Sie im obigen Snippet sehen können, greift die Zeile okhttp3.Response response = chain.proceed(request); auf die Antwort des Servers zu. Folglich können wir den Statuscode mit if (response.code() == 500) überprüfen und dann die ServerIsBrokenActivity öffnen.

Eine andere Möglichkeit besteht darin, die execute-Methode in Retrofits OkClient zu überschreiben. In meinem Fall habe ich nach einem bestimmten Antwortheader gesucht, also ging es ungefähr so:

OkClient client = new OkClient(okHttpClient) {
    @Override
    public retrofit.client.Response execute(retrofit.client.Request request) throws IOException {
        retrofit.client.Response response = super.execute(request);

        // Do whatever with 'response', such as looking for the value of a particular header:

        List<retrofit.client.Header> headers = response.getHeaders();
        for (retrofit.client.Header header : headers) {
            if (MY_HEADER.equalsIgnoreCase(header.getName())) {
                this.savedValue = header.getValue();
                break;
            }
        }

        return response;
    }
};

RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder()
        .setEndpoint(API_BASE_URL)
        .setClient(client);
0