Retrofitは、REST APIとのやり取りをシンプルに行うインターフェースを提供するライブラリです。HTTP通信に使うclientをセットできるんですが、明示的にセットしていない場合の挙動でちょっとハマったのでメモしておきます。
OkHttpのクラスパスがあるかどうかで挙動が変わる
結論から言うと、プロジェクト内にOkHttpのクラスパスがあるかどうかで挙動が変わります。
retrofit.RestAdapter#ensureSaneDefaults()
を見ると、デフォルトのclientProviderをセットしています。
private void ensureSaneDefaults() {
if (converter == null) {
converter = Platform.get().defaultConverter();
}
if (clientProvider == null) {
clientProvider = Platform.get().defaultClient();
}
// 略
}
Platform#defaultClient()
を見ると、OkHttpのクラスパスがあるかどうかで AndroidApacheClient か UrlConnectionClient を使うようになっています。
@Override Client.Provider defaultClient() {
final Client client;
if (hasOkHttpOnClasspath()) {
client = OkClientInstantiator.instantiate();
} else {
client = new UrlConnectionClient();
}
return new Client.Provider() {
@Override public Client get() {
return client;
}
};
}
RetrofitでOkHttpを使う場合は、公式ページのINTEGRATION WITH OKHTTPに書いてあるとおり、 okhttp
と okhttp-urlconnection
を依存関係に追加しなければなりません。
When using Retrofit together with OkHttp, OkHttp (version 1.6.0 or newer) and OkHttp-UrlConnection are now required.
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.squareup.okhttp:okhttp:2.0.0'
何が問題か
okhttp、okhttp-urlconnectionを明示的に依存関係に入れている場合は問題ないです。
問題があるのは、気づかないうちに他のライブラリがokhttpに依存していて、意図せずclientがokhttpに切り替わり挙動が変わるケースです。
一例をあげると、OkHttpを使うとFollowRedirectが有効になっているので問題ないですが、AndroidApacheClientだとデフォルト無効なので、予期せず 302 Moved Temporarily
エラーが発生することがあります。
結論
Retrofitを使う場合は、clientを明示的にセットするか、okhttpを依存関係に加えましょう。
ちなみにまだリリースされていないですが、retrofit:2.0.0はデフォルトが必ずokhttpを使うようになっているので問題なさそうです。
以上です!