VolleyでCookieって・・・どうすんねん?
AndroidでVolleyを使ってMultipart/form-data形式で送信してみるでAndroidでVolleyを使ってHTTPでMultipart/form-data形式で送信する例を書きましたが、送信する相手がAPI形式で同時に認証もやってくれるならいいのですが、そうではない場合があります。
例えば、API形式のI/Fが全く用意されていないく、ブラウザからHTMLで送信する画面しか用意されていない場合があります。この場合、通常
- ログイン
- Multipart/form-data形式で送信
- ログアウト
という流れになりますが1.でサーバ側からのレスポンスヘダーのset-cookieで払い出されたcookieをHTTPヘダーに設定して2.で送信しないと「ログインされていません」となります。
Volleyを使って1.、2.、3.で3回通信する場合、1.のレスポンスのset-cookieを2.、3.に引き継ぐ必要があります。
CookieManagerを使う
自前で1.のレスポンスヘダーのset-cookieを2.、3.のリクエストヘダーに設定する実装をゴリゴリ書いてもいいのですが(cookieの仕様がわかってしまえばそんなに難しくない)CookieManagerを使えばもっと簡単にできます。
CookieManagerとは?
CookieManagerはjava6くらいからありますが、
https://docs.oracle.com/javase/jp/8/docs/api/java/net/CookieManager.html
のクラスの説明文を見ると、
use
CookieHandler <------- HttpURLConnection
^
| impl
| use
CookieManager -------> CookiePolicy
| use
|--------> HttpCookie
| ^
| | use
| use |
|--------> CookieStore
^
| impl
|
Internal in-memory implementation
HTTP通信にHttpURLConnectionを使っていれば、CookieManagerがCookiePolicyに従って、CookeStoreに保持してくれます。
CookeStoreはインタフェースであり、デフォルトではインメモリにCookieが保持されます。CookeStoreの独自実装を自作することにより、ファイル等にシリアライズすることも可能です。
VolleyはHttpStackに
- HttpClientStack
- HurlStack
が使えますが、どちらにしてもHttpURLConnectionを使っているので、CookieManagerでCookieの保持ができます。
CookieManagerを実装に追加する
前回、AndroidでVolleyを使ってMultipart/form-data形式で送信してみる作成したクラスにCookieManagerを実装を追加します。
class HttpPostMultiPart(private val context: Context) {
/** CookieStore */
private var cookieStore: CookieStore // ※1
/** CookieManager */
private var cookieManager: CookieManager = CookieManager()
init {
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL)
CookieHandler.setDefault(cookieManager)
cookieStore = cookieManager.cookieStore // ※1
}
・・・(後略)
たった、これだけです。
- CookieManagerを初期化して、
- Cookieポリシーを設定(全て受入、全て拒否、同一サーバの場合)
- CookieHandlerでデフォルトのCookieManagerを設定
これだけだと、CookieManagerのクラスとリクエスト、レスポンスを作る処理と何の関連も無いのでは?と思うかもしれませんが、CookieManagerのJavaDocの冒頭の説明の通り、内部でHttpURLConnectionが使われていれば自動的に、CookieManagerがCookieStoreにCookieを保持してくれます。
ただ、
- ログイン
- Multipart/form-data形式で送信
- ログアウト
とCookieを引き継げばいいだけであれば※1の部分も要りません。※1が要らなければ実質、追加するのはたったの5行です。
内部でCookieがどうなっているか見たい、Cookieを操作したい場合は※1が必要です。
内部でCookieがどうなっているか見たいはこのようにします
cookieStore.cookies.forEach { cookie ->
Log.d(TAG, "name = $cookie.name, value = ${cookie.value}")
}
独自のCookieをを追加した場合は
CookieStore#add(URI uri, HttpCookie cookie)
を使います。
VolleyだとCookieを使うのは意外と簡単でした。処理にはほとんど影響しません。