2014-02-19 103 views
85

我無法在Retrofit API中找到用於記錄完整請求/響應主體的相關方法。 I 希望在Profiler中有所幫助(但它只提供有關響應的元數據)。我試圖在Builder中設置日誌級別,但是這對我也沒有幫助:如何使用Retrofit-Android登錄請求和響應主體?

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

編輯:此代碼現在正在工作。我不知道爲什麼它不工作得更早。可能是因爲我正在使用一些舊版本的改造。

+0

你有沒有想過這個?文件中說'FULL'應該給身體,但它似乎並沒有。 – theblang

+1

@mattblang:我不知道以前有什麼錯,但是這段代碼現在正在工作。 – SlowAndSteady

+0

[Logging with Retrofit 2]可能的重複(http://stackoverflow.com/questions/32514410/logging-with-retrofit-2) – bryant1410

回答

79

我用setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG")),它幫了我。
UPDATE。
您也可以嘗試進行調試目的使用retrofit.client.Response作爲響應模型

+2

'AndroidLog',那是什麼類? – theblang

+0

它帶有Retrofit庫。 –

+2

我明白了。不幸的是,這不會給你'response body',儘管它在文檔中聲明LogLevel.FULL **應該給你'response body'。 – theblang

8

似乎沒有成爲一個方式做基本的+體,但你可以使用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 ] 

所以它應該很容易通過調節自定義過濾器來登錄基本+體。我正在使用黑名單,但也可以根據您的需要使用白名單。

77

改造2.0

UPDATE:@by馬庫斯Pöhls

登錄改造2

改造2完全依賴於OkHttp任何網絡操作。由於OkHttp是Retrofit 2的對等依賴項,因此一旦Retrofit 2作爲穩定版本發佈,您就不需要添加其他依賴項。

OkHttp 2.6.0附帶一個日誌攔截器作爲內部依賴關係,您可以直接將它用於您的Retrofit客戶端。 Retrofit 2.0.0-beta2仍然使用OkHttp 2.5.0。未來的版本會將依賴關係提升到更高的OkHttp版本。這就是爲什麼你需要手動導入日誌攔截器。將以下行添加到您的build.gradle文件中的gradle導入中以獲取日誌攔截器依賴項。

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

You can also visit Square's GitHub page about this interceptor

添加記錄到改造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的日誌記錄攔截器有四個日誌級別:NONE,BASIC,標題,主體。我們會逐步介紹每個日誌級別並描述它們的輸出。

進一步信息,請訪問:Retrofit 2 — Log Requests and Responses

OLD答:

在改造2沒有記錄了。開發團隊刪除了日誌記錄功能。說實話,記錄功能不是那麼可靠。傑克沃頓明確指出,所記錄的消息或對象是假定的值,並且他們無法證明是真實的。到達服務器的實際請求可能具有更改的請求主體或其他內容。

即使缺省情況下沒有集成日誌記錄,您也可以利用任何Java記錄器並在自定義的OkHttp攔截器中使用它。

約2改造的詳細信息,請參閱: Retrofit — Getting Started and Create an Android Client

+1

還有一個特定的帖子來登錄Retrofit 2.0:https://futurestud.io/blog/retrofit-2-log-requests-and-responses/ – peitek

+0

偉大的方式來製作一切都比它應該更復雜。讓我想起澤西1與澤西2伐木。更多樣板代碼.... – breakline

+0

以這種方式添加攔截器現在將在OkHttp v3中導致UnsupportedOperationException。新的方法是: OkHttpClient.Builder()addInterceptor(記錄) https://github.com/square/okhttp/issues/2219 – Amagi82

27

更新改造2.0.0-β3

現在,你必須與製造商使用okhttp3。老攔截器也不起作用。此響應是針對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); 
    } 
    } 
} 

獎金

我知道它的offtopic,但我覺得它很酷。

如果有一個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(我的項目)。

+2

很好的答案。在這個時候它應該是最高的。 – Mussa

1

如果您使用的是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(); 
2

下面代碼工作對於用頭和無頭打印日誌請求&響應。 注意:只是評論。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(); 
相關問題