android cookies java,Pass cookies from HttpURLConnection (java.net.CookieManager) to WebView (androi...

问题

I\'ve seen answers about how this should work with the old DefaultHttpClient

but there\'s not a good example for HttpURLConnection

I\'m using HttpURLConnection to make requests to a web application. At the start of the my Android application, I use CookieHandler.setDefault(new CookieManager()) to automatically deal with the session cookies, and this is working fine.

At some point after the login, I want to show live pages from the web application to the user with a WebView instead of downloading data behind the scenes with HttpURLConnection. However, I want to use the same session I established earlier to prevent the user from having to login again.

How do I copy the cookies from java.net.CookieManager used by HttpURLConnection to android.webkit.CookieManager used by WebView so I can share the session?

回答1:

I would like to suggest a completely different approach to your problem. Instead of copying cookies from one place to another (manual sync), let's make HttpURLConnection and WebViews use the same cookie storage.

This completely eliminates the need for sync. Any cookie updated in any one of them, will be immediately and automatically reflected in the other.

To do this, create your own implementation of java.net.CookieManager which forwards all requests to the WebViews' webkit android.webkit.CookieManager.

Implementation:

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> 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> get(URI uri, Map> 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> res = new java.util.HashMap>();

// 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();

}

}

and finally use it by doing this on your application initialization:

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

回答2:

As compared with DefaultHttpClient, there are a few extra steps. The key difference is how to access the existing cookies in HTTPURLConnection:

Call CookieHandler.getDefault() and cast the result to java.net.CookieManager.

With the cookie manager, call getCookieStore() to access the cookie store.

With the cookie store, call get() to access the list of cookies for the given URI.

Here's a complete example:

@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 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

...

}

回答3:

I magically solved all my cookie problems with this one line in onCreate:

CookieHandler.setDefault(new CookieManager());

回答4:

I had the same problem, and this is my solution :

Just after login (it's important because before, you may be don't have cookie yet) using httpurlconnection POST (after getResponseCode), I do :

responseCode = connexion.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

final String COOKIES_HEADER = "Set-Cookie";

cookie = connexion.getHeaderField(COOKIES_HEADER);

...

}

(where cookie is a public String in my class)

And in the webview activity, where I want to display a web page from server using WebView, I do :

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

As my webview is in a fragment, I had to use getActivity() for the Context, I also had to specify android.webkit. before CookieManager otherwise it cannot be resolved (import java.net instead of android.webkit cookie manager).

cookie is the same String as above (in my Fragment, I had to recover it using :

cookie = getArguments().getString(COOKIE);

and in my MainActivity, I send it by :

Bundle arg = new Bundle();

arg.putString(Fragment_Cameras.COOKIE, cookie);

fragment.setArguments(arg);

I hop this can help !

来源:https://stackoverflow.com/questions/12731211/pass-cookies-from-httpurlconnection-java-net-cookiemanager-to-webview-android

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值