【问题标题】:Add headers to the interceptor on retrofit 2 [duplicate]在改造 2 上向拦截器添加标头 [重复]
【发布时间】:2017-02-08 05:19:17
【问题描述】:

由于我需要使用 Retrofit 2 并且我需要记录请求背后发生的事情,因此解决方案是添加请求拦截器。我添加了一个从 okhttp wiki page 获取的拦截器,我还根据需要添加了一些其他更改,并在构建阶段将其设置为 okhttp 客户端,但它没有按我预期的那样工作。令我惊讶的是,当我将自定义拦截器设置为 okhttp 客户端时,GsonConverter 无法将响应 json 解析为 java 对象。

这是来自我的拦截器的代码

public class LoggingInterceptor implements Interceptor {

private final static String TAG = "RI";

private HashMap<String, String> headersMap = null;
public LoggingInterceptor(HashMap<String, String> headers) {
    this.headersMap = headers;
}

@Override
public Response intercept(Chain chain) throws IOException {

    Request request = chain.request();
    Request.Builder reqBuilder = request.newBuilder();
    Log.e(TAG, "Headers on the map -> " + headersMap.size());
    for (String header : headersMap.keySet()) {
        reqBuilder.addHeader(header, headersMap.get(header));
    }

    request = reqBuilder.build();
    long timeRequest = System.nanoTime();
    Log.d(TAG, String.format(Locale.getDefault(), "Sending %s with %s", request.url(), request.headers()));

    Response response = chain.proceed(request);

    Log.d(TAG, "<<<=========================================>>>");
    long timeResponse = System.nanoTime();
    Log.d(TAG, String.format(Locale.getDefault(), "Receiving %s in %s%n%s", response.request().url(), ((timeResponse - timeRequest)/1e6d), response.headers()));
    Log.d(TAG, "Data: " + response.body().string());
    Log.d(TAG, "Code: " + response.code());

    return response;
}

}

下面是我将它添加到 Okhttp 客户端的方法

private OkHttpClient createHttpClient(){
    if(client == null){

        String strUserAgent = "tm-vc=" + BuildConfig.VERSION_CODE + "-devid=" + (getDeviceID().isEmpty() ? "0" : getDeviceID());
        HashMap<String, String> headers = new HashMap<>();
        headers.put(HEADER_ACCEPT,      "application/json; charset=utf-8");
        headers.put(HEADER_USER_AGENT,  strUserAgent);
        String cookie =  getSessionCookie();
        if(cookie != null && !cookie.isEmpty())
            headers.put(HEADER_COOKIE,  cookie);
        
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.addInterceptor(new LoggingInterceptor(headers));
        builder.retryOnConnectionFailure(true);
        client = builder.build();
    }
    return client;
}

为了测试我所说的,我只需要评论这一行builder.addInterceptor(new LoggingInterceptor(headers));,如果您评论该行,则调用改造 onResponse 并成功(有效,解析 json),如果不调用 onFailure。

那么我自己的拦截器实现缺少什么?

问题本身是什么? 如何使用拦截器向请求中添加标头?

是的,我可以使用注释,但标题的值是静态的。

注意:我使用的是全新的 Retrofit 2。

【问题讨论】:

  • 为什么不使用 HttpLoggingInterceptor? github.com/square/okhttp/tree/master/okhttp-logging-interceptor
  • @robert-banyai 它也失败了,我还需要向它添加标题
  • 对不起,还是不明白你的问题,你可以给你的客户端添加多个拦截器。我用同样的方法,效果很好。
  • @RobertBanyai 现在我明白了,HttpLogging 拦截器失败,因为版本与 okhttp 版本不匹配。现在可以了
  • 当你做Log.d(TAG, "Data: " + response.body().string());时,你正在消耗身体。

标签: java android json retrofit2 okhttp3


【解决方案1】:

您可以将 HttpLoggingInterceptorRetrofit 2 一起使用,如下所示

1) Api 客户端

// imports
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

---

// Method to create instance of Service
public ApiService getService() {

    // Interceptor to Log the Request
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    // Level.BODY prints Urls, Params and Response
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    // Create the Client
    OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

    // Initialize retrofit instance
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    // Creates the instance of Web Service Representation
    return retrofit.create(ApiService.class);
}

2) Gradle 依赖项

// Retrofit 2 dependency
compile 'com.squareup.retrofit2:retrofit:2.1.0'
// GSON for Parsing into POJOs
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
// Logging Interceptor to Log the  Request
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
// OK HTTP dependency (for Compatibility)
compile 'com.squareup.okhttp3:okhttp:3.4.1'

3) 同样,您可以将自己的自定义(例如标题)添加到 Retrofit

【讨论】:

  • 您的解决方案有效,但这样我就无法在请求中注入请求标头,并且在 example 中说这是可能的。我尝试复制该示例并添加一些功能,但没有成功。
  • 查看这个:*See if this could solve your issue. 注意:拦截器是订购的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2019-12-07
相关资源
最近更新 更多