使用自定义Interceptor时OkHttpClient请求头丢失,静态/动态添加正常
记录请求头时遇到的问题
自定义拦截器与ApiClient实现
AuthInterceptor类
public class AuthInterceptor implements Interceptor { private SessionManagement sessionManagement; public AuthInterceptor(Context ctx) { this.sessionManagement = new SessionManagement(ctx); } @NonNull @Override public Response intercept(@NonNull Chain chain) throws IOException { Request request = chain.request(); Request.Builder requestBuilder = request.newBuilder(); // if token saved, add to request String token = sessionManagement.getSessionToken(); if (token != null) { requestBuilder.addHeader("Authorization", "Bearer " + token); } return chain.proceed(requestBuilder.build()); } }
ApiClient类
public class ApiClient { public static final String BASE_URL = "some/url"; public static Retrofit retrofit = null; public static Retrofit getApiClient(Context context) { if (retrofit == null) { Gson gson = new GsonBuilder() .setLenient() .create(); AuthInterceptor authInterceptor = new AuthInterceptor(context); HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context)); OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(authInterceptor) .addInterceptor(logging) .cookieJar(cookieJar) .build(); retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .client(okHttpClient) .build(); } return retrofit; } }
日志内容
2023-01-26 13:35:53.361 7841-7924 okhttp.OkHttpClient com.example.releasesapp I --> POST http://.../loginuser.php 2023-01-26 13:35:53.361 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Content-Type: application/json; charset=UTF-8 2023-01-26 13:35:53.361 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Content-Length: 41 2023-01-26 13:35:53.361 7841-7924 okhttp.OkHttpClient com.example.releasesapp I {"email":"t@t.com","password":"test1234"} 2023-01-26 13:35:53.361 7841-7924 okhttp.OkHttpClient com.example.releasesapp I --> END POST (41-byte body) 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I <-- 200 OK http://.../loginuser.php (96ms) 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Date: Thu, 26 Jan 2023 12:35:54 GMT 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Server: Apache/2.4.54 (Win64) OpenSSL/1.1.1p PHP/8.1.10 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I X-Powered-By: PHP/8.1.10 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Expires: Thu, 19 Nov 1981 08:52:00 GMT 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Cache-Control: no-store, no-cache, must-revalidate 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Pragma: no-cache 2023-01-26 13:35:53.458 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Set-Cookie: PHPSESSID=l08iqa7cs8tvt1bfnijkl1r7d8; path=/ 2023-01-26 13:35:53.459 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Content-Length: 194 2023-01-26 13:35:53.459 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Keep-Alive: timeout=5, max=100 2023-01-26 13:35:53.459 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Connection: Keep-Alive 2023-01-26 13:35:53.459 7841-7924 okhttp.OkHttpClient com.example.releasesapp I Content-Type: text/html; charset=UTF-8 2023-01-26 13:35:53.459 7841-7924 okhttp.OkHttpClient com.example.releasesapp I {"status_code":200,"auth_token":"TEMPTOKEN","user":{"id":"30","full_name":null,"username":"t","password_hash":"$2y","email":"t@t.com"}} 2023-01-26 13:35:53.459 7841-7924 okhttp.OkHttpClient com.example.releasesapp I <-- END HTTP (194-byte body)
问题与解答
1. 为什么日志里看不到Authorization请求头?
你当前的日志是登录请求的日志,此时还未完成登录,sessionManagement.getSessionToken()返回null,拦截器自然不会添加Authorization头。这是符合逻辑的——登录请求本身就是用来获取token的,不需要携带token。
验证方式:登录成功保存token后,发起其他需要鉴权的请求,此时日志中就能看到Authorization: Bearer xxx请求头;也可以临时在拦截器中手动赋值测试token,观察日志是否显示该头。
2. 注释自定义OkHttpClient后,日志仍显示okhttp.OkHttpClient是否正常?
这是正常的,但需注意两点:
- Retrofit默认会自动创建一个
OkHttpClient实例处理请求,所以即使不自定义,底层依然使用OkHttp,日志中会显示okhttp.OkHttpClient。 - 若注释自定义代码后仍看到完整日志(含请求体、响应体),是因为
ApiClient中的retrofit是静态变量,第一次初始化后会持续存在,不会重新创建。解决方法:清理应用缓存或重启应用,让retrofit重新初始化,此时默认OkHttp不带HttpLoggingInterceptor,就不会输出这类日志了。
内容的提问来源于stack exchange,提问作者dan
相关产品推荐
相关产品推荐

