本稿ではOkHttpのApplication InterceptorとNetwork Interceptorの役割について書きました.
内容はOkHttp公式wiki - Interceptorsと被っていますが, メモとして残します.
Interceptor
OkHttpでは処理に割り込めるポイントが2つあり, 必要に応じて使い分けます.
アプリケーションとOkHttpとのコミュニケーションに割り込むInterceptorをApplicationInterceptor
, OkHttpとネットワークとのコミュニケーションに割り込むInterceptorをNetworkInterceptor
と呼びます.
これらはOkHttpClient.Builder
を経由して設定できます.
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.addNetworkInterceptor(new LoggingInterceptor())
.build();
挙動の違い
OkHttpはアプリケーションが楽できるように様々な処理を代行します.
Redirect, Retryの処理はアプリとのコミュニケーションなしに, OkHttpに閉じて行われます.
そういったアプリとのコミュニケーションが発生しないケースではApplicationInterceptor
が使えません.
Redirect, Retryの処理はネットワークとのコミュニケーションになります. ここへ割り込むにはNetworkInterceptor
が使えます.
ただし, Cacheレスポンスが働く場合はネットワークとのコミュニケーションが発生しません.
そういったネットワークとのコミュニケーションが発生しないケースではNetworkInterceptor
が使えません.
各Interceptorのポイントを下記に纏めます.
ApplicationInterceptor
- RedirectやRetryといった中間応答には反応できない
- Cacheレスポンスにも反応する
- アプリケーションが発行するオリジナルリクエストが監視対象
NetworkInterceptor
- RedirectやRetryといった中間応答にも反応できる
- Cacheレスポンスには反応できない
- ネットワークへ発行されるリクエストが監視対象
監視対象リクエストについて. OkHttpはアプリからのリクエストを加工して通信します.
この時, アプリからリクエストされたオリジナルの内容はApplicationInterceptor
が補足します.
その後, OkHttpが加工したリクエストはNetworkInterceptor
が補足します.
client.newCall(new Request.Builder()
.url(url)
.build())
.execute();
上記の単純なGETリクエストを投げるコードで, ApplicationInterceptor
, NetworkInterceptor
それぞれにHttpLoggingInterceptorを設定した場合のログ出力を確認します.
// ApplicationInterceptorによる出力
--> GET http://127.0.0.1:54817/ http/1.1
--> END GET
// NetworkInterceptorによる出力
--> GET http://127.0.0.1:54817/ http/1.1
Host: 127.0.0.1:54817
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.2.0
--> END GET
リクエストを加工する工程がみて取れました.
他にも, OkHttpにCookie管理を任せてCookieヘッダをログで確認したい場合はNetworkInterceptor
を使います.
CookieManager cookieManager
= new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
CookieHandler.setDefault(cookieManager);
server.enqueue(new MockResponse()
.addHeader("Set-Cookie: a=hoge;")
.addHeader("Set-Cookie: b=foo;"));
server.enqueue(new MockResponse());
client = client.newBuilder()
.cookieJar(new JavaNetCookieJar(cookieManager))
.build();
requestGet(urlWithIpAddress(server, "/"));
requestGet(urlWithIpAddress(server, "/"));
--> GET http://127.0.0.1:56899/ http/1.1
Host: 127.0.0.1:56899
Connection: Keep-Alive
Accept-Encoding: gzip
Cookie: a=hoge; b=foo
User-Agent: okhttp/3.2.0
--> END GET
以上です.