如何使用 OkHttp 在 Android 上实现 cookie 处理?

Posted

技术标签:

【中文标题】如何使用 OkHttp 在 Android 上实现 cookie 处理?【英文标题】:How to implement cookie handling on Android using OkHttp? 【发布时间】:2014-08-07 11:20:05 【问题描述】:

使用Square https://github.com/square/okhttp的OkHttp,我该怎么做:

    检索从服务器返回的 cookie 为即将到来的请求存储 cookie 在后续请求中使用存储的 cookie 更新后续请求返回的cookie

理想情况下,cookie 会在每次请求时自动存储、重新发送和更新。

【问题讨论】:

【参考方案1】:

对于OkHttp3,一个简单的accept-all、非持久化CookieJar实现可以如下:

OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new CookieJar() 
        private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) 
            cookieStore.put(url, cookies);
        

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) 
            List<Cookie> cookies = cookieStore.get(url);
            return cookies != null ? cookies : new ArrayList<Cookie>();
        
    )
    .build();

或者,如果您更喜欢使用java.net.CookieManager,请在您的项目中包含okhttp-urlconnection,其中包含JavaNetCookieJar,这是一个委托给java.net.CookieHandler的包装类:

dependencies 
    compile "com.squareup.okhttp3:okhttp:3.0.0"
    compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0"


CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new JavaNetCookieJar(cookieManager))
    .build();

【讨论】:

如此自动保存而我无需做什么?重启后工作? 不,该示例适用于非持久性 cookie jar。对于持久性解决方案,您可以实现自己的,例如***.com/a/25462286/836540,并用 JavaNetCookieJar 包装。 顺便说一句,url 是服务器的“完整 URL”,它只会在向完全相同的 URL 发出请求时发送 cookie。您可能希望将 cookieStore.put(url, cookies); 替换为 cookieStore.put(url.host(), cookies); 对于 loadForRequest,coookieStore.get(url.host());。并将HashMap&lt;HttpUrl, List&lt;Cookie&gt;&gt; 替换为HashMap&lt;String, ...&gt; @hidro 我如何构造 Cookie? 这是错误的。 saveFromResponse 替换列表而不是合并它们。这意味着设置任何 cookie 都会清除之前请求中设置的所有 cookie。【参考方案2】:

Pre OkHttp 3, 您可以将 CookieHandler 传递给 OkHttpClient 实例。您可以使用 java.net 中的 CookieManager 实现,也可以根据需要实现自己的。选择最适合您需求的政策。

OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);

OkHttp 将从 Responses 接收到的 cookie 保存到 CookieHandler 中,并在发送请求时从中读取。它将这样做以匹配请求/响应 URI。

【讨论】:

需要注意的重要一点:CookieManager 不是持久的。下次启动应用时,cookie jar 将是空的。 @JesseWilson,那么如何让它持久化? 持久 cookie 尚未实现。如果你需要 em,你需要制作你自己的 CookieStore。 @JesseWilson 你是对的。这是一个有助于持久化 CoockieJar github.com/franmontiel/PersistentCookieJar 的库 setCookieHandler 方法不在这里 okhttp 3.0【参考方案3】:

我需要共享默认的 Cookie Jar (CookieManager.getInstance()),所以这对我来说似乎没问题。

return new CookieJar() 

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) 
            CookieManager cookieManager = CookieManager.getInstance();

            for (Cookie cookie : cookies) 
                cookieManager.setCookie(url.toString(), cookie.toString());
            
        

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) 
            CookieManager cookieManager = CookieManager.getInstance();
            List<Cookie> cookies = new ArrayList<>();
            if (cookieManager.getCookie(url.toString()) != null) 
                String[] splitCookies = cookieManager.getCookie(url.toString()).split("[,;]");
                for (int i=0; i<splitCookies.length; i++) 
                    cookies.add(Cookie.parse(url, splitCookies[i].trim()));
                
            
            return cookies;
        
    ;

【讨论】:

谢谢它真的很好用。做得好。简单的解决方案,谢谢!! hii @hmac 你的这种方法对我有用。你能指导我如何在用户注销时清除 cookie 吗? 我解决了清除 cookie 的问题。这是链接可能对某人有帮助 ***.com/a/50505170/8159810

以上是关于如何使用 OkHttp 在 Android 上实现 cookie 处理?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 1.5 上实现推送?

如何在 Android 上实现 Material Design 展开/折叠列表?

如何使用 Xamarin Android 在 Edit Text 上实现 TextWatcher 接口?

如何在 Android 上实现 XMPP Server 以及与 GCM 的通信?

如何在 Android 平板电脑上实现主从视图 Qt/QML?

如何在 Android Activity 上实现多线程?