2014-02-19 90 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(); 
相关问题