web-dev-qa-db-fra.com

Comment enregistrer le corps de la demande et de la réponse avec Retrofit-Android?

Je ne trouve pas de méthodes pertinentes dans l'API Retrofit pour consigner des corps de demande/réponse complets. Je m'attendais à de l'aide dans le profileur (mais il ne propose que des méta-données sur la réponse). J'ai essayé de définir le niveau de journalisation dans le générateur, mais cela ne m'aide pas non plus:

RestAdapter adapter = (new RestAdapter.Builder()).
                setEndpoint(baseUrl).
                setRequestInterceptor(interceptor).
                setProfiler(profiler).
                setClient(client).
                setExecutors(MyApplication.getWebServiceThreadPool()).
                setLogLevel(LogLevel.FULL).
                setLog(new RestAdapter.Log() {
                    @Override
                    public void log(String msg) {
                        Log.i(TAG, msg);
                    }
                }).
                build();

EDIT: Ce code fonctionne maintenant. Je ne sais pas pourquoi cela ne fonctionnait pas plus tôt. Peut-être parce que j'utilisais une version plus ancienne de la modification.

116
Jaguar

J'ai utilisé setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG")), cela m'a aidé.
MISE À JOUR.
Vous pouvez également essayer le débogage en utilisant retrofit.client.Response comme modèle de réponse.

87
Alex Dzeshko

Retrofit 2.0 :

MISE À JOUR: @by Marcus Pöhls

Ouverture de session Retrofit 2

Retrofit 2 repose entièrement sur OkHttp pour toute opération de réseau. Étant donné qu'OkHttp est une dépendance entre pairs de Retrofit 2, vous n'aurez pas besoin d'ajouter de dépendance supplémentaire une fois que Retrofit 2 est publié en tant que version stable.

OkHttp 2.6.0 est livré avec un intercepteur de journalisation en tant que dépendance interne et vous pouvez l’utiliser directement pour votre client Retrofit. Retrofit 2.0.0-beta2 utilise toujours OkHttp 2.5.0. Les versions futures vont augmenter la dépendance à des versions plus récentes d'OkHttp. C’est pourquoi vous devez importer manuellement l’intercepteur de journalisation. Ajoutez la ligne suivante à vos importations Gradle dans votre fichier build.gradle pour extraire la dépendance de l'intercepteur de journalisation.

compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'

Vous pouvez également visiter la page GitHub de Square sur cet intercepteur

Ajouter la journalisation à Retrofit 2

Lors du développement de votre application et à des fins de débogage, il est agréable d’avoir une fonction de journalisation intégrée pour afficher les informations de requête et de réponse. La journalisation n'étant plus intégrée par défaut dans Retrofit 2, nous devons ajouter un intercepteur de journalisation pour OkHttp. Heureusement, OkHttp est déjà livré avec cet intercepteur et il vous suffit de l'activer pour votre OkHttpClient.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();  
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();   
// add your other interceptors …
// add logging as last interceptor
httpClient.addInterceptor(logging);  // <-- this is the important line!
Retrofit retrofit = new Retrofit.Builder()  
        .baseUrl(API_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(httpClient.build())
        .build();

Nous vous recommandons d'ajouter la journalisation en tant que dernier intercepteur, car cela enregistrera également les informations que vous avez ajoutées avec les intercepteurs précédents à votre demande.

Niveaux de journalisation

Si vous enregistrez trop d’informations, votre moniteur Android explose. C’est pourquoi l’intercepteur de journalisation d’OkHttp dispose de quatre niveaux de journalisation: NONE, BASIC, HEADERS, BODY. Nous allons vous guider à travers chacun des niveaux de journalisation et décrire leurs résultats.

plus d'informations s'il vous plaît visitez: Retrofit 2 - Log demandes et réponses

ANCIENNE RÉPONSE:

pas de connexion à Retrofit 2 plus. L'équipe de développement a supprimé la fonctionnalité de journalisation. Pour être honnête, la fonctionnalité de journalisation n’était pas si fiable de toute façon. Jake Wharton a explicitement déclaré que les messages ou objets consignés étaient les valeurs supposées et qu’ils ne pouvaient pas être vérifiés comme étant vrais. La requête réelle qui arrive sur le serveur peut avoir un corps de requête modifié ou autre chose.

Même s'il n'y a pas de journalisation intégrée par défaut, vous pouvez exploiter tout enregistreur Java et l'utiliser dans un intercepteur OkHttp personnalisé.

pour plus d'informations sur Retrofit 2, veuillez vous reporter à: Retrofit - Mise en route et création d'un client Android

106
Dhaval Jivani

Mise à jour pour Retrofit 2.0.0-beta3

Maintenant, vous devez utiliser okhttp3 avec le constructeur. De plus, l'ancien intercepteur ne fonctionnera pas. Cette réponse est adaptée pour Android.

Voici un rapide copier coller pour vous avec les nouveaux éléments.

1. Modifiez votre fichier de classement en

  compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
  compile "com.squareup.retrofit2:converter-gson:2.0.0-beta3"
  compile "com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3"
  compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'

2. Vérifiez cet exemple de code:

avec les nouvelles importations. Vous pouvez supprimer Rx si vous ne l'utilisez pas, supprimez également ce que vous n'utilisez pas.

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.GsonConverterFactory;
import retrofit2.Retrofit;
import retrofit2.RxJavaCallAdapterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;

public interface APIService {

  String ENDPOINT = "http://api.openweathermap.org";
  String API_KEY = "2de143494c0b2xxxx0e0";

  @GET("/data/2.5/weather?appid=" + API_KEY) Observable<WeatherPojo> getWeatherForLatLon(@Query("lat") double lat, @Query("lng") double lng, @Query("units") String units);


  class Factory {

    public static APIService create(Context context) {

      OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
      builder.readTimeout(10, TimeUnit.SECONDS);
      builder.connectTimeout(5, TimeUnit.SECONDS);

      if (BuildConfig.DEBUG) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        builder.addInterceptor(interceptor);
      }

      //Extra Headers

      //builder.addNetworkInterceptor().add(chain -> {
      //  Request request = chain.request().newBuilder().addHeader("Authorization", authToken).build();
      //  return chain.proceed(request);
      //});

      builder.addInterceptor(new UnauthorisedInterceptor(context));
      OkHttpClient client = builder.build();

      Retrofit retrofit =
          new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();

      return retrofit.create(APIService.class);
    }
  }
}

Bonus

Je sais que c'est offtopic mais je trouve ça cool.

Dans le cas où il existe un code d'erreur http de non autorisé , voici un intercepteur. J'utilise Eventbus pour transmettre l'événement.

import Android.content.Context;
import Android.os.Handler;
import Android.os.Looper;
import com.androidadvance.ultimateandroidtemplaterx.BaseApplication;
import com.androidadvance.ultimateandroidtemplaterx.events.AuthenticationErrorEvent;

import de.greenrobot.event.EventBus;
import Java.io.IOException;
import javax.inject.Inject;
import okhttp3.Interceptor;
import okhttp3.Response;

public class UnauthorisedInterceptor implements Interceptor {

  @Inject EventBus eventBus;

  public UnauthorisedInterceptor(Context context) {
    BaseApplication.get(context).getApplicationComponent().inject(this);
  }

  @Override public Response intercept(Chain chain) throws IOException {
    Response response = chain.proceed(chain.request());
    if (response.code() == 401) {
      new Handler(Looper.getMainLooper()).post(() -> eventBus.post(new AuthenticationErrorEvent()));
    }
    return response;
  }
}

prendre le code de https://github.com/AndreiD/UltimateAndroidTemplateRx (mon projet).

30
OWADVL

Il ne semble pas y avoir de moyen de faire basic + body, mais vous pouvez utiliser FULL et filtrer les en-têtes que vous ne voulez pas.

RestAdapter adapter = new RestAdapter.Builder()
                          .setEndpoint(syncServer)
                          .setErrorHandler(err)
                          .setConverter(new GsonConverter(gson))
                          .setLogLevel(logLevel)
                          .setLog(new RestAdapter.Log() {
                              @Override
                              public void log(String msg) {
                                  String[] blacklist = {"Access-Control", "Cache-Control", "Connection", "Content-Type", "Keep-Alive", "Pragma", "Server", "Vary", "X-Powered-By"};
                                  for (String bString : blacklist) {
                                      if (msg.startsWith(bString)) {
                                          return;
                                      }
                                  }
                                  Log.d("Retrofit", msg);
                              }
                          }).build();

Il semble que lors du remplacement du journal, le corps est préfixé par une balise semblable à

[ 02-25 10:42:30.317 25645:26335 D/Retrofit ]

il devrait donc être facile de se connecter basic + body en ajustant le filtre personnalisé. J'utilise une liste noire, mais une liste blanche peut également être utilisée en fonction de vos besoins.

9
Xeridea

le code ci-dessous fonctionne pour les deux avec en-tête et sans en-tête pour imprimer la requête et la réponse du journal. Remarque: Il suffit de commenter la ligne .addHeader () si vous n'utilisez pas d'en-tête.

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                //.addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
                .addNetworkInterceptor(new Interceptor() {

                    @Override

                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request().newBuilder()
                                // .addHeader(Constant.Header, authToken)
                                   .build();
                        return chain.proceed(request);
                    }
                }).build();

        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.baseUrl)
                .client(client) // This line is important
                .addConverterFactory(GsonConverterFactory.create())
                .build();
3
Mukesh Parmar

Si vous utilisez Retrofit2 et okhttp3, vous devez savoir qu'Interceptor fonctionne par file d'attente. Ajoutez donc loggingInterceptor à la fin, après vos autres intercepteurs:

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        if (BuildConfig.DEBUG)
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);

 new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(new CatalogInterceptor(context))
                .addInterceptor(new OAuthInterceptor(context))
                .authenticator(new BearerTokenAuthenticator(context))
                .addInterceptor(loggingInterceptor)//at the end
                .build();
2
NickUnuchek

J'espère que ce code vous aidera à vous connecter.
il vous suffit d’ajouter un intercepteur dans votre Build.Gradle puis de créer RetrofitClient.

Premier pas

Ajouter cette ligne à votre build.gradle

 implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1' 

Deuxième étape

Faites votre client de rénovation


   public class RetrofitClient {

    private Retrofit retrofit;
    private static OkHttpClient.Builder httpClient =
            new OkHttpClient.Builder();
    private static RetrofitClient instance = null;
    private static ApiServices service = null;
    private static HttpLoggingInterceptor logging =
            new HttpLoggingInterceptor();

    private RetrofitClient(final Context context) {
        httpClient.interceptors().add(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
                Request originalRequest = chain.request();
                Request.Builder builder = originalRequest.newBuilder().
                        method(originalRequest.method(), originalRequest.body());
                okhttp3.Response response = chain.proceed(builder.build());
                /*
                Do what you want
                 */
                return response;
            }
        });

        if (BuildConfig.DEBUG) {
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            // add logging as last interceptor
            httpClient.addInterceptor(logging);
        }

        retrofit = new Retrofit.Builder().client(httpClient.build()).
                baseUrl(Constants.BASE_URL).
                addConverterFactory(GsonConverterFactory.create()).build();
        service = retrofit.create(ApiServices.class);
    }


    public static RetrofitClient getInstance(Context context) {
        if (instance == null) {
            instance = new RetrofitClient(context);
        }
        return instance;
    }

    public ApiServices getApiService() {
        return service;
    }
}

Appel

RetrofitClient.getInstance(context).getApiService().yourRequestCall(); 

2
Talha Bilal

ZoomX - Android Logger Interceptor est un excellent intercepteur qui peut vous aider à résoudre votre problème.

0
Ibrahim AbdelGawad

Pour Android studio avant 3.0 (en utilisant Android motinor)
https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses
https://www.youtube.com/watch?v=vazLpzE5y9M

Et pour Android studio à partir de la version 3.0 (l'utilisation du profileur Android comme moniteur Android est remplacée par le profileur Android)
https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-Android-studio-profiler

0
shehzy