web-dev-qa-db-fra.com

Retrofit - Interception des réponses à l'échelle mondiale

Je souhaite intercepter toutes les réponses reçues par le moteur de conversion et rechercher le code d'erreur HTTP, par exemple l'erreur 403.

Je suis conscient que je peux utiliser le rappel (échec de l'erreur RetrofitError) de chaque demande et vérifier les 403, mais je voudrais envelopper la réponse globalement.

Je peux voir que l'interception de demande est possible, mais je ne vois pas d'option similaire pour la réponse.

Aucune suggestion?

24
aviran

J'ai pu réaliser cela en ajoutant un intercepteur à OkHttpClient utilisé par la modernisation.

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

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

Comme vous pouvez le voir dans l'extrait ci-dessus, la ligne okhttp3.Response response = chain.proceed(request); permet d'accéder à la réponse du serveur. Par conséquent, nous pouvons vérifier le code d'état avec if (response.code() == 500), puis ouvrir la ServerIsBrokenActivity.

0

Une autre possibilité consiste à remplacer la méthode execute dans la variable OkClient de Retrofit. Dans mon cas, je cherchais un en-tête de réponse spécifique.

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