9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OkHttp3 で クライアント側から setCookie する

Last updated at Posted at 2017-03-25

課題

Androidとサーバーで通信(HTTPベース)するとき、サーバーの都合でどうしてもAndroidクライアント側でCookieセットしてほしいという要望があり、OkHttp3( http://square.github.io/okhttp/ )でAndroid側からsetCookieする方法を考えてみました。

利用したライブラリ okhttp/3.6.0

前置き

すでに解決案があるかとおもい探してみると類似の話題がいくつかありますが、私の求めているものと微妙に違っていた(or 解決しきれていなかった)ので自分でつくることにしました。

解決策

OkHttp3CookieHelper というヘルパークラスをつくりました。
以下のようにすると、クライアント側で独自のクッキーを強制的にセットします。
もちろん、サーバーから発行されたその他のクッキーもハンドリングされます。
永続化の仕組みは必要になったらいれます。当面オンメモリで問題なさそうです。

以下のコードは特にプラットフォーム依存していないのでPure JavaでもAndroidでも動作します。

サンプルコード


		String url = "https://example.com/webapi";

		OkHttp3CookieHelper cookieHelper = new OkHttp3CookieHelper();
		cookieHelper.setCookie(url, "cookie_name", "cookie_value");
		
		OkHttpClient client = new OkHttpClient.Builder()
				.cookieJar(cookieHelper.cookieJar())
				.build();

		Request request = new Request.Builder()
				.url(url)
				.build();

※ヘルパークラスはgraldeで**compile 'org.riversun:okhttp3-cookie-helper:1.0.1'**でロードできます。

ヘルパークラスのソースコード

OkHttp3CookieHelper.java
public class OkHttp3CookieHelper {

	private final Map<String, List<Cookie>> mServerCookieStore = new ConcurrentHashMap<String, List<Cookie>>();

	private Map<String, List<Cookie>> mClientCookieStore = new ConcurrentHashMap<String, List<Cookie>>();

	private final CookieJar mCookieJar = new CookieJar() {
		@Override
		public List<Cookie> loadForRequest(HttpUrl url) {

			List<Cookie> serverCookieList = mServerCookieStore.get(url.host());

			if (serverCookieList == null) {
				serverCookieList = new ArrayList<Cookie>();
			}

			final List<Cookie> clientCookieStore = mClientCookieStore.get(url.host());

			if (clientCookieStore != null) {
				serverCookieList.addAll(clientCookieStore);
			}

			return serverCookieList != null ? serverCookieList : new ArrayList<Cookie>();
		}

		@Override
		public void saveFromResponse(HttpUrl url, List<Cookie> unmodifiableCookieList) {
			mServerCookieStore.put(url.host(), new ArrayList<Cookie>(unmodifiableCookieList));
		}

	};

	public void setCookie(String url, Cookie cookie) {

		final String host = HttpUrl.parse(url).host();

		List<Cookie> cookieListForUrl = mClientCookieStore.get(host);
		if (cookieListForUrl == null) {
			cookieListForUrl = new ArrayList<Cookie>();
			mClientCookieStore.put(host, cookieListForUrl);
		}
		putCookie(cookieListForUrl, cookie);

	}

	public void setCookie(String url, String key, String value) {
		final HttpUrl httpUrl = HttpUrl.parse(url);
		setCookie(url, Cookie.parse(httpUrl, key + "=" + value));
	}

	public void setCookie(HttpUrl httpUrl, String key, String value) {
		setCookie(httpUrl.host(), Cookie.parse(httpUrl, key + "=" + value));
	}

	public CookieJar cookieJar() {
		return mCookieJar;
	}

	private void putCookie(List<Cookie> storedCookieList, Cookie newCookie) {

		Cookie oldCookie = null;
		for (Cookie storedCookie : storedCookieList) {

			// create key for comparison
			final String oldCookieKey = storedCookie.name() + storedCookie.path();
			final String newCookieKey = newCookie.name() + newCookie.path();

			if (oldCookieKey.equals(newCookieKey)) {
				oldCookie = storedCookie;
				break;
			}
		}
		if (oldCookie != null) {
			storedCookieList.remove(oldCookie);
		}
		storedCookieList.add(newCookie);
	}

}

公開先

コードは以下にて公開

github

gradle

compile 'org.riversun:okhttp3-cookie-helper:1.0.1'

maven

<dependency>
<groupId>org.riversun</groupId>
<artifactId>okhttp3-cookie-helper</artifactId>
<version>1.0.1</version>
</dependency>
9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?