Як увійти в систему запиту та відповіді за допомогою Retrofit-Android?


129

Я не можу знайти відповідні методи в API модернізації для реєстрації повних органів запиту / відповіді. Я очікував деякої допомоги в Profiler (але він пропонує лише метадані про відповідь). Я спробував встановити рівень журналу в Builder, але це також не допомагає мені:

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: Цей код працює зараз. Я не знаю, чому раніше не працювало. Можливо, тому, що я використовував старіший варіант доопрацювання.


Did you ever figure this out? The documentation says that FULL is supposed to give the body but it doesn't seem to.
theblang

1
@mattblang : I don't know what was wrong earlier, but this code is working now.
Jaguar

Possible duplicate of Logging with Retrofit 2
bryant1410


Можливо, миттєвий запуск зіпсував smth, якщо він не працював раніше
deathangel908

Відповіді:


91

Я використовував setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG")), це мені допомогло.
ОНОВЛЕННЯ.
Ви також можете спробувати для налагодження використовувати retrofit.client.Responseяк модель відповіді


2
AndroidLog, який клас це?
theblang

Поставляється з бібліотекою Retrofit.
Олексій Джешко

2
Я бачу. На жаль, це не дає тобі response body, хоча це вказується в документі, який LogLevel.FULL повинен дати тобі response body.
theblang

Це можна побачити за допомогою "YOUR_LOG_TAG" у лог-коді для Android на вкладці багатослівної.
rajeesh

4
LogLevel.Full не існує в

121

Модернізація 2.0 :

ОНОВЛЕННЯ: @by Marcus Pöhls

Модернізація 2

Retrofit 2 повністю покладається на OkHttp для будь-якої роботи в мережі. Оскільки OkHttp є однорідною залежністю Retrofit 2, вам не потрібно буде додавати додаткову залежність, як тільки Retrofit 2 буде випущений як стабільний випуск.

OkHttp 2.6.0 поставляється з перехоплювачем журналу як внутрішньою залежністю, і ви можете безпосередньо використовувати його для свого клієнта Retrofit. Retrofit 2.0.0-beta2 все ще використовує OkHttp 2.5.0. Майбутні випуски підсилюють залежність до вищих версій OkHttp. Ось чому вам потрібно вручну імпортувати перехоплювач журналу. Додайте наступний рядок до імпорту gradle у файлі build.gradle, щоб отримати залежність від перехоплювача журналу.

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

Ви також можете відвідати сторінку GitHub Square щодо цього перехоплювача

Додати журнал до вдосконалення 2

Під час розробки програми та для налагодження приємно інтегрувати функцію журналу, щоб відображати інформацію про запити та відповіді. Оскільки в Retrofit 2 журнал журналу вже не інтегрований за замовчуванням, нам потрібно додати перехоплювач журналу для OkHttp. На щастя, OkHttp вже поставляється з цим перехоплювачем, і вам потрібно лише активувати його для вашого 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();

Ми рекомендуємо додати журнал як останній перехоплювач, оскільки він також запише інформацію, яку ви додали з попередніми перехоплювачами до свого запиту.

Рівні журналу

Запис занадто великої кількості інформації підірве ваш монітор Android, тому перехоплювач журналу OkHttp має чотири рівні журналу: НІКОЛЬНИЙ, ОСНОВНИЙ, ГОЛОВНІ, ТІЛЬКИ. Ми проведемо вас через кожен з рівнів журналу та опишемо їх вихід.

Додаткову інформацію, будь ласка, відвідайте: Retrofit 2 - Запити та відповіді журналу

СТАРИЙ ВІДПОВІДЬ:

більше не входило в систему Retrofit 2. Команда розробників видалила функцію ведення журналу. Якщо чесно сказати, функція ведення журналу не була такою надійною. Джейк Уортон прямо заявив, що зареєстровані повідомлення або об'єкти - це припущені значення, і їх не можна було довести як істинні. Фактичний запит, який надходить на сервер, може мати змінене тіло запиту або щось інше.

Незважаючи на те, що за замовчуванням не існує інтегрованого журналу, ви можете використовувати будь-який реєстратор Java та використовувати його у спеціалізованому перехоплювачі OkHttp.

Додаткову інформацію про Retrofit 2 див. у статті: Retrofit - Початок роботи та створення Android-клієнта


1
Існує також публікація, специфічна для входу в Retrofit 2.0: futurestud.io/blog/retrofit-2-log-requests-and- responses
peitek

Чудовий спосіб зробити все складніше, ніж повинно бути. Нагадує мені про засідання Джерсі 1 проти Джерсі 2. Більше кодового коду ....
перерва

Додавання перехоплювачів таким чином тепер призведе до UnsupportedOperationException в OkHttp v3. Новий спосіб: OkHttpClient.Builder (). AddInterceptor (logging) .build () github.com/square/okhttp/isissue/2219
Amagi82

@JawadLeWywadi так, використовуючи цей код, можна надрукувати корпус
Dhaval Jivani

Для Retrofit 2 це набагато простіше.
Gary99

31

Оновлення для Retrofit 2.0.0-beta3

Тепер ви повинні використовувати okhttp3 з builder. Також старий перехоплювач не буде працювати. Ця відповідь розроблена для Android.

Ось швидка копія для вас з новими матеріалами.

1. Змініть файл gradle в

  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. Перевірте цей зразок коду:

з новим імпортом. Ви можете видалити Rx, якщо ви його не використовуєте, а також видалити те, що не використовуєте.

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

Бонус

Я знаю, що це офтопік, але я вважаю це крутим.

У випадку, якщо код помилки http несанкціонований , ось перехоплювач. Я використовую eventbus для передачі події.

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;
  }
}

код взяти з https://github.com/AndreiD/UltimateAndroidTemplateRx (мій проект).


9

Здається, немає способу зробити basic + body, але ви можете використовувати FULL та фільтрувати заголовки, які ви не хочете.

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

Здається, що при перезаписі журналу тіло має префікс тегу, подібного до

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

тож слід легко зафіксувати базовий + body, регулюючи спеціальний фільтр. Я використовую чорний список, але білий список також може бути використаний залежно від ваших потреб.


4

нижче код працює як із заголовком, так і без заголовка для друку запиту журналу та відповіді. Примітка. Просто коментуйте рядок .addHeader (), якщо не використовується заголовок.

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

Я сподіваюся, що цей код допоможе вам вести реєстрацію.
вам просто потрібно додати перехоплювач у свій Build.Gradleтоді makeRetrofitClient .

Перший крок

Додайте цей рядок до свого build.gradle

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

Другий крок

Зробіть свого клієнта з модернізації


   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;
    }
}

Дзвінок

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

2

Якщо ви використовуєте Retrofit2 та okhttp3, то вам потрібно знати, що Interceptor працює за чергою. Тому додайте loggingInterceptor наприкінці після інших перехоплювачів:

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


0

Для андроїд-студії до 3.0 (використовуючи android motinor) https://futurestud.io/tutorials/retrofit-2-log-requests-and- responses

https://www.youtube.com/watch?v=vazLpzE5y9M

А для андроїд-студії від 3.0 і вище (використання андроїд-профілера як андроїд-монітора замінено андроїд-профілером)
https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-android-studio-profiler

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.