Лесозаготовки с модифицированной 2
Я пытаюсь получить точный JSON, который отправляется в запросе. Вот мой код:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor(){
@Override public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Log.e(String.format("nrequest:n%snheaders:n%s",
request.body().toString(), request.headers()));
com.squareup.okhttp.Response response = chain.proceed(request);
return response;
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client).build();
но я вижу только это в журналах:
request:
com.squareup.okhttp.RequestBody@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json
как я должен сделать правильный журнал, учитывая удаление setLog() и setLogLevel() который мы использовали для использования с Retrofit 1?
15 ответов:
в Retrofit 2 вы должны использовать HttpLoggingInterceptor.
добавить зависимость к
build.gradle:compile 'com.squareup.okhttp3:logging-interceptor:3.9.1'создать
Retrofitобъект следующим образом:HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://backend.example.com") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build(); return retrofit.create(ApiClient.class);вышеуказанное решение дает вам сообщения logcat очень похожие на старые, установленные
setLogLevel(RestAdapter.LogLevel.FULL)в случае
java.lang.ClassNotFoundException:более старая версия дооснащения может потребовать более старой
logging-interceptorверсия. Взгляните на разделы комментариев для подробности.
здесь
Interceptorкоторый регистрирует как тела запроса, так и ответы (используя Timber, основанный на примере из документов OkHttp и некоторых других ответов SO):public class TimberLoggingInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); long t1 = System.nanoTime(); Timber.i("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers()); Timber.v("REQUEST BODY BEGIN\n%s\nREQUEST BODY END", bodyToString(request)); Response response = chain.proceed(request); ResponseBody responseBody = response.body(); String responseBodyString = response.body().string(); // now we have extracted the response body but in the process // we have consumed the original reponse and can't read it again // so we need to build a new one to return from this method Response newResponse = response.newBuilder().body(ResponseBody.create(responseBody.contentType(), responseBodyString.getBytes())).build(); long t2 = System.nanoTime(); Timber.i("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()); Timber.v("RESPONSE BODY BEGIN:\n%s\nRESPONSE BODY END", responseBodyString); return newResponse; } private static String bodyToString(final Request request){ try { final Request copy = request.newBuilder().build(); final Buffer buffer = new Buffer(); copy.body().writeTo(buffer); return buffer.readUtf8(); } catch (final IOException e) { return "did not work"; } } }
попробуйте это:
Request request = chain.request(); Buffer buffer = new Buffer(); request.body().writeTo(buffer); String body = buffer.readUtf8();после этого, в
bodyесть JSON, который вас интересует.
Я не знаю, вернется ли setLogLevel() в окончательной версии 2.0 Retrofit, но сейчас вы можете использовать перехватчик для ведения журнала.
хороший пример можно найти в OkHttp wiki:https://github.com/square/okhttp/wiki/Interceptors
OkHttpClient client = new OkHttpClient(); client.interceptors().add(new LoggingInterceptor()); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://www.yourjsonapi.com") .addConverterFactory(GsonConverterFactory.create()) .client(client) .build();
для тех, кто нуждается в высоком уровне регистрации в модернизации, используйте перехватчик, как это
public static class LoggingInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); long t1 = System.nanoTime(); String requestLog = String.format("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers()); //YLog.d(String.format("Sending request %s on %s%n%s", // request.url(), chain.connection(), request.headers())); if(request.method().compareToIgnoreCase("post")==0){ requestLog ="\n"+requestLog+"\n"+bodyToString(request); } Log.d("TAG","request"+"\n"+requestLog); Response response = chain.proceed(request); long t2 = System.nanoTime(); String responseLog = String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()); String bodyString = response.body().string(); Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString); return response.newBuilder() .body(ResponseBody.create(response.body().contentType(), bodyString)) .build(); //return response; } } public static String bodyToString(final Request request) { try { final Request copy = request.newBuilder().build(); final Buffer buffer = new Buffer(); copy.body().writeTo(buffer); return buffer.readUtf8(); } catch (final IOException e) { return "did not work"; } }`вежливость: https://github.com/square/retrofit/issues/1072#
основной проблемой, с которой я столкнулся, было динамическое добавление заголовков и регистрация их в debug logcat. Я попытался добавить два перехватчика. Один для регистрации и один для добавления заголовков на ходу (авторизация токенов). Проблема в том, что мы можем .addInterceptor или .addNetworkInterceptor. Как сказал мне Джейк Уортон: "сетевые перехватчики всегда приходят после перехватчиков приложений. См.https://github.com/square/okhttp/wiki/Interceptors". Так вот рабочий пример с заголовками и журналы:
OkHttpClient httpClient = new OkHttpClient.Builder() //here we can add Interceptor for dynamical adding headers .addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request().newBuilder().addHeader("test", "test").build(); return chain.proceed(request); } }) //here we adding Interceptor for full level logging .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create())) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(httpClient) .baseUrl(AppConstants.SERVER_ADDRESS) .build();
Если вы используете Retrofit2 и okhttp3, то вам нужно знать, что перехватчик работает по очереди. Поэтому добавьте 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))//first .addInterceptor(new OAuthInterceptor(context))//second .authenticator(new BearerTokenAuthenticator(context)) .addInterceptor(loggingInterceptor)//third, log at the end .build();
вы также можете добавить Стето Facebook и посмотреть на сетевые следы в Chrome: http://facebook.github.io/stetho/
final OkHttpClient.Builder builder = new OkHttpClient.Builder(); if (BuildConfig.DEBUG) { builder.networkInterceptors().add(new StethoInterceptor()); }затем откройте "chrome: / / inspect" в Chrome...
лучший способ сделать это правильно в Retrofit 2, чтобы добавить перехватчик регистратора в качестве networkInterceptor это будет печатать сетевые заголовки и пользовательские заголовки тоже. Важно помнить, что перехватчик работает как стек и обязательно добавьте регистратор в конце всего.
OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.addInterceptor(new MyCustomInterceptor()); builder.connectTimeout(60, TimeUnit.SECONDS); builder.readTimeout(60, TimeUnit.SECONDS); builder.writeTimeout(60, TimeUnit.SECONDS); // important line here builder.addNetworkInterceptor(LoggerInterceptor());
большая часть ответа здесь охватывает почти все, кроме этого инструмента, один из самых крутых способов увидеть журнал.
Это Facebook по Stetho. Это превосходный инструмент для мониторинга / регистрации сетевого трафика вашего приложения на google chrome. Вы также можете найти здесь на Github.
Я нашел способ для печати журнала в Retrofit
OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (BuildConfig.DEBUG) { Log.e(getClass().getName(), request.method() + " " + request.url()); Log.e(getClass().getName(), "" + request.header("Cookie")); RequestBody rb = request.body(); Buffer buffer = new Buffer(); if (rb != null) rb.writeTo(buffer); LogUtils.LOGE(getClass().getName(), "Payload- " + buffer.readUtf8()); } return chain.proceed(request); } }) .readTimeout(60, TimeUnit.SECONDS) .connectTimeout(60, TimeUnit.SECONDS) .build(); iServices = new Retrofit.Builder() .baseUrl("Your Base URL") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() .create(Your Service Interface .class);работает для меня.
для дооснащения 2.0.2 код выглядит как
**HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient.Builder httpClient=new OkHttpClient.Builder(); httpClient.addInterceptor(logging);** if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) **.client(httpClient.build())** .build(); }
Котлин Код
val interceptor = HttpLoggingInterceptor() interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) val client = OkHttpClient.Builder().addInterceptor(interceptor).build() val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() return retrofit.create(PointApi::class.java)
Эй, ребята, я уже нашел решение:
public static <T> T createApi(Context context, Class<T> clazz, String host, boolean debug) { if (singleton == null) { synchronized (RetrofitUtils.class) { if (singleton == null) { RestAdapter.Builder builder = new RestAdapter.Builder(); builder .setEndpoint(host) .setClient(new OkClient(OkHttpUtils.getInstance(context))) .setRequestInterceptor(RequestIntercepts.newInstance()) .setConverter(new GsonConverter(GsonUtils.newInstance())) .setErrorHandler(new ErrorHandlers()) .setLogLevel(debug ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE)/*LogLevel.BASIC will cause response.getBody().in() close*/ .setLog(new RestAdapter.Log() { @Override public void log(String message) { if (message.startsWith("{") || message.startsWith("[")) Logger.json(message); else { Logger.i(message); } } }); singleton = builder.build(); } } } return singleton.create(clazz); }

Comments