HttpURLConnection (java.net.CookieManager) 和 WebView (android.webkit.CookieManager) 之间 cookie 的两种同步方式 [英] Two way sync for cookies between HttpURLConnection (java.net.CookieManager) and WebView (android.webkit.CookieManager)

查看:26
本文介绍了HttpURLConnection (java.net.CookieManager) 和 WebView (android.webkit.CookieManager) 之间 cookie 的两种同步方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不幸的是,Android 有很多 cookie 管理器.HttpURLConnection 的 cookie 由 java.net.CookieManager 维护,WebView 的 cookie 由 android.webkit.CookieManager<维护/代码>.这些 cookie 存储库是独立的,需要手动同步.

Unfortunately, there's a multitude of cookie managers for Android. The cookies for HttpURLConnection are maintained by java.net.CookieManager and the cookies for WebView are maintained by android.webkit.CookieManager. These cookie repositories are separate and require manual synchronization.

我的应用程序同时使用 HttpURLConnections 并显示 WebViews(它是原生 HTML 混合体).当然,我希望两者都共享所有 cookie - 所以我将有一个透明的会话.

My app uses both HttpURLConnections and shows WebViews (it's a native-HTML hybrid). Naturally, I want both to share all cookies - so I will have a transparent session all across.

更具体地说:

  1. 在 HttpURLConnection 中设置/更改 cookie 时,我希望 WebView 也能看到此更改.
  2. 在 WebView 中设置/更改 cookie 时,我希望下一个 HttpURLConnections 也能看到此更改.

简单地说 - 我正在寻找双向同步.或者甚至更好,让它们都使用相同的 cookie 存储库.您可以假设两者同时处于活动状态(例如在不同的选项卡上).

Simply put - I'm looking for a two-way sync. Or even better, to have them both use the same cookie repository. You can assume both are active in the same time (like on different tabs).

问题:

  1. 有没有办法让两者都使用同一个 cookie 存储库?

  1. Is there a way to make both use the same cookie repository?

如果没有,手动同步的推荐做法是什么?我应该在什么时候同步以及如何同步?

If not, what is the recommended practice to do the manual sync? When exactly should I sync and how?

相关问题:这个问题 解决了类似的问题,但仅实现了单向同步 (HttpURLConnection -> WebView).

Related Question: This question tackles a similar issue, but only implements one-way sync (HttpURLConnection -> WebView).

迄今为止我最好的想法:我真的很想避免手动同步,所以我试图思考如何让两者使用相同的存储库.也许我可以创建自己的核心处理程序来扩展 java.net.CookieManager.我将使用 java.net.CookieHandler.setDefault() 将其设置为核心 cookie 处理程序.它的实现将是 android.webkit.CookieManager 处理程序实例的代理(对于每个函数,我将简单地访问 webkit 管理器).

My Best Idea So Far: I really want to avoid a manual sync, so I tried to think how to make both use the same repository. Maybe I can create my own core handler which extends java.net.CookieManager. I will set it as the core cookie handler using java.net.CookieHandler.setDefault(). Its implementation will be a proxy to the android.webkit.CookieManager handler instance (for every function I'll simply access the webkit manager).

推荐答案

我已经实现了我自己的想法.它实际上很酷.我已经创建了自己的 java.net.CookieManager 实现,它将所有请求转发到 WebViews 的 webkit android.webkit.CookieManager.这意味着不需要同步,HttpURLConnection 使用与 WebView 相同的 cookie 存储.

I've implemented my own idea. It's actually pretty cool. I've created my own implementation of java.net.CookieManager which forwards all requests to the WebViews' webkit android.webkit.CookieManager. This means no sync is required and HttpURLConnection uses the same cookie storage as the WebViews.

WebkitCookieManagerProxy 类:

import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class WebkitCookieManagerProxy extends CookieManager 
{
    private android.webkit.CookieManager webkitCookieManager;

    public WebkitCookieManagerProxy()
    {
        this(null, null);
    }

    public WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy)
    {
        super(null, cookiePolicy);

        this.webkitCookieManager = android.webkit.CookieManager.getInstance();
    }

    @Override
    public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException 
    {
        // make sure our args are valid
        if ((uri == null) || (responseHeaders == null)) return;

        // save our url once
        String url = uri.toString();

        // go over the headers
        for (String headerKey : responseHeaders.keySet()) 
        {
            // ignore headers which aren't cookie related
            if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;

            // process each of the headers
            for (String headerValue : responseHeaders.get(headerKey))
            {
                this.webkitCookieManager.setCookie(url, headerValue);
            }
        }
    }

    @Override
    public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException 
    {
        // make sure our args are valid
        if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");

        // save our url once
        String url = uri.toString();

        // prepare our response
        Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();

        // get the cookie
        String cookie = this.webkitCookieManager.getCookie(url);

        // return it
        if (cookie != null) res.put("Cookie", Arrays.asList(cookie));
        return res;
    }

    @Override
    public CookieStore getCookieStore() 
    {
        // we don't want anyone to work with this cookie store directly
        throw new UnsupportedOperationException();
    }
}

并通过在您的应用程序初始化时执行此操作来使用它:

android.webkit.CookieSyncManager.createInstance(appContext);
// unrelated, just make sure cookies are generally allowed
android.webkit.CookieManager.getInstance().setAcceptCookie(true);

// magic starts here
WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL);
java.net.CookieHandler.setDefault(coreCookieManager);

测试

我的初步测试表明它运行良好.我看到在 WebViews 和 HttpURLConnection 之间共享 cookie.我希望我不会遇到任何问题.如果您尝试并发现任何问题,请发表评论.

My initial testing show this is working well. I see cookies shared between the WebViews and HttpURLConnection. I hope I'll not run into any issues. If you try this out and discover any problem, please comment.

这篇关于HttpURLConnection (java.net.CookieManager) 和 WebView (android.webkit.CookieManager) 之间 cookie 的两种同步方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆