将cookies从HttpURLConnection(java.net.CookieManager)传递给WebView(android.webkit.CookieManager)

我已经看到如何应用旧的DefaultHttpClient答案,但没有一个很好的例子HttpURLConnection

我正在使用HttpURLConnection向Web应用程序发出请求。 在我的Android应用程序的开始,我使用CookieHandler.setDefault(new CookieManager())来自动处理会话cookie,这是工作正常。

login后的某个时刻,我想通过WebView将实时页面从Web应用程序显示给用户,而不是使用HttpURLConnection在后台下载数据。 但是,我想使用之前build立的同一会话来防止用户再次login。

如何将cookie从HttpURLConnection使用的java.net.CookieManager复制到WebView使用的android.webkit.CookieManager ,以便我可以共享会话?

Solutions Collecting From Web of "将cookies从HttpURLConnection(java.net.CookieManager)传递给WebView(android.webkit.CookieManager)"

我想build议一个完全不同的方法来解决你的问题。 而不是将cookies从一个地方复制到另一个地方(手动同步),让我们让HttpURLConnection和WebViews使用相同的 cookie存储。

这完全消除了同步的需要。 其中任何一个更新的cookie都会立即自动反映到另一个cookie中。

为此,创build您自己的java.net.CookieManager实现,它将所有请求转发到WebViews的webkit android.webkit.CookieManager。

执行:

 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); } 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); 

DefaultHttpClient相比,还有一些额外的步骤。 主要区别在于如何访问HTTPURLConnection的现有cookie:

  1. 调用CookieHandler.getDefault()并将结果转换为java.net.CookieManager
  2. 使用cookiepipe理器,调用getCookieStore()来访问cookie存储。
  3. 使用cookie存储,调用get()来访问给定URI的cookie列表。

这是一个完整的例子:

 @Override protected void onCreate(Bundle savedInstanceState) { // Get cookie manager for WebView // This must occur before setContentView() instantiates your WebView android.webkit.CookieSyncManager webCookieSync = CookieSyncManager.createInstance(this); android.webkit.CookieManager webCookieManager = CookieManager.getInstance(); webCookieManager.setAcceptCookie(true); // Get cookie manager for HttpURLConnection java.net.CookieStore rawCookieStore = ((java.net.CookieManager) CookieHandler.getDefault()).getCookieStore(); // Construct URI java.net.URI baseUri = null; try { baseUri = new URI("http://www.example.com"); } catch (URISyntaxException e) { // Handle invalid URI ... } // Copy cookies from HttpURLConnection to WebView List<HttpCookie> cookies = rawCookieStore.get(baseUri); String url = baseUri.toString(); for (HttpCookie cookie : cookies) { String setCookie = new StringBuilder(cookie.toString()) .append("; domain=").append(cookie.getDomain()) .append("; path=").append(cookie.getPath()) .toString(); webCookieManager.setCookie(url, setCookie); } // Continue with onCreate ... } 

我使用onCreate中的这一行神奇地解决了我所有的cookie问题:

CookieHandler.setDefault(new CookieManager());

我有同样的问题,这是我的解决scheme:

刚刚login(这是重要的,因为以前,你可能没有cookie)使用httpurlconnection POST(之后getResponseCode),我做:

  responseCode = connexion.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { final String COOKIES_HEADER = "Set-Cookie"; cookie = connexion.getHeaderField(COOKIES_HEADER); ... } 

(其中cookie是我class的公共string)

在webview活动中,我想使用WebView从服务器显示网页,我这样做:

  String url = "http://toto.com/titi.html"; // the url of the page you want to display CookieSyncManager.createInstance(getActivity()); CookieSyncManager.getInstance().startSync(); android.webkit.CookieManager cookieManager = android.webkit.CookieManager.getInstance(); cookieManager.setAcceptCookie(true); cookieManager.removeSessionCookie(); cookieManager.setCookie(url, cookie); CookieSyncManager.getInstance().sync(); 

由于我的webview是在一个片段中,我不得不使用getActivity()作为上下文,我还必须指定android.webkit。 在CookieManager之前,否则无法parsing(导入java.net而不是android.webkit cookiepipe理器)。

cookie是相同的string如上(在我的片段,我不得不恢复使用:

  cookie = getArguments().getString(COOKIE); 

在我的MainActivity中,我通过以下方式发送:

  Bundle arg = new Bundle(); arg.putString(Fragment_Cameras.COOKIE, cookie); fragment.setArguments(arg); 

我跳这可以帮助!