Interceptors
是一個簡單的攔截器,可以方便監控、重寫 request 也可以針對 response 進行加工HttpLoggingInterceptor
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
val client = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.build()
val retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(BASE_URL)
.build()
–
Interceptors
其實是在夾在 request 與 response 中間的一個 interfacesource: https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor
Interceptor
呢?class LoggingInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val t1 = System.nanoTime()
logger.info(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()))
response = chain.proceed(request)
val t2 = System.nanoTime()
logger.info(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()))
return response
}
}
chain.request()
取得當前的 requestchain.proceed(request)
將 request 跑完變成 response–
class InvalidTokenInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
// check request has auth token
if (response.request.header("Authorization") == null) {
return response
}
// check response token invalid
if (!response.isSuccessful && response.code == 401) {
// token invalid
val newToken = refreshToken() ?: return response
// retry api
response.close()
var requestBuilder = request.newBuilder()
if (request.header("Authorization") != null) {
requestBuilder = requestBuilder
.removeHeader("Authorization")
.addHeader("Authorization", "Bearer $newToken")
}
val newRequest = requestBuilder.build()
return chain.proceed(newRequest)
}
return response
}
fun refreshToken(): String? {
val call = service.refreshToken()
val response = call.execute()
if (response.isSuccessful && response.body() != null) {
return userEntity.accessToken
}
return null
}
}
–
1. 先 chain.proceed(request) 跑完取得一個 response
2. 然後判斷這個 request 的 header 有沒有 Authorization,, 如果沒有那就直接 return 當前的 response 就好結束
3. 若 header有 Authorization 那我就進行判斷,當前 token 是否 invalid,若否則也直接 return 當前的 response 就好
4. 在 token invalid 的狀況下我們可以先丟一次 refresh token api 已取得新的 token 字串
5. 然後重新用舊的 request 產生一個新的 request build
6. 再將剛剛取得的新 token 字串重新塞入 header
7. 最後再將新的 request 跑完變成新的 response 回傳