1. YukiAsu

    Posted

    YukiAsu
Changes in title
+Volleyでcookieをちゃんと扱う(あるいはHttpURLConnectionの話)
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,55 @@
+# 前回までのあらすじ
+以前[VolleyでCookieとUserAgentをまとめていじりたい](http://qiita.com/YukiAsu/items/2ed3dc6e780bfe93af29)とは言ったのだけれど、どうにもcookieの扱いが無理やりすぎてコレジャナイ感があった。実際"responseを拾えばSet-Cookieを回収できる"とは言ったものの、単純なString扱いなので例えばDomainごとに制御したりとかができないのだ。
+
+Volleyの同じQueueで自分のAPIとTwitter両方ともつついたりしてると、双方に双方のCookieを流し込むことになる。そんなの気持ち悪い!なんとかしたい!(というかセキュリティ的にアカン)
+
+# HurlStack、あるいはHttpURLConnectionをちゃんと考える
+そもそもVolleyを使う為に仕方なくHurlStackを使ってる、という意識だったので理解が薄すぎた。どう考えても標準でCookieを扱う仕組みがあるべきだし、あるだろう。HurlStack方面でそれを調べて見る。
+
+HurlStack。とはいえこいつの中ではHttpURLConnectionを使っているにすぎない。そしてこれにはきちんとCookieを操作するための標準的な仕組みが存在する。それが `CookieHandler`や`CookieManager`だ。
+
+CookieManagerを使えばCookieStoreが取得できる。中身はHttpCookieというのが詰まっていて、もうこれはほぼゴールだ。getName()やgetValue()だけじゃない、getDomain()もできちゃったりしてやりたい放題だ。これに任せよう。
+
+きちんと設定してあげればVolley以外でもHttpURLConnectionを使っている箇所すべてにCookieが染み渡るのも素晴らしい。
+
+# RequestQueueに入れてみる
+以上の点を踏まえ、前回同様RequestQueueをこう書き換えてみた
+
+```java:RequestQueueWithCookie
+// CookieManagerを作ってDefaultに設定
+final CookieManager cookieManager = new CookieManager();
+CookieHandler.setDefault(cookieManager);
+
+// Volleyのリクエストキューを生成
+RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext(), new HurlStack(){
+ @Override
+ public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
+ throws IOException, AuthFailureError {
+ Map newHeaders = new HashMap();
+ newHeaders.putAll(additionalHeaders);
+ // セッション維持のためcookieとUserAgentを設定する
+ newHeaders.put("User-Agent", "ユーザーエージェント");
+ // 実際はoldCookieはどこからともなく持ってきてStoreに登録する
+ CookieStore store = cookieManager.getCookieStore();
+ HttpCookie oldCookie = new HttpCookie("クッキーのname", "クッキーのvalue");
+ store.add(URI.create("domain"), oldCookie);
+
+ // responseを待ってCookieを回収する
+ HttpResponse response = super.performRequest(request, newHeaders);
+ // cookieの回収
+ List<HttpCookie> cookies = store.getCookies();
+ if (cookies.size() > 0) {
+ // あればクッキーを保存
+ // cookies.get(0)とかをどうにかこうにか保存します
+ }
+
+ return response;
+ }
+});
+```
+
+これならたぶん有効期限とかもよしなに処理してくれるし、絶対こっちのほうが健全だと思った。
+
+# 参考
+[どうしてJaveでCookieが取得できないんだろう?](http://tomott.cocolog-nifty.com/blog/2010/08/javecookie1-87d.html)
+もうだいぶ昔の話で表題のバグはなおってるっぽいけれど、中の動きがよくわかった。(気がする)