将 cookie 从 HttpURLConnection (java.net.CookieManager) 传递到 WebView (android.webkit.CookieManager)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12731211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pass cookies from HttpURLConnection (java.net.CookieManager) to WebView (android.webkit.CookieManager)
提问by quietmint
I've seen answers about how this should work with the old
DefaultHttpClient
but there's not a good example forHttpURLConnection
我已经看到了关于这应该如何与旧的一起工作的答案,
DefaultHttpClient
但没有一个很好的例子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.
我正在使用HttpURLConnection
向 Web 应用程序发出请求。在我的 Android 应用程序开始时,我使用CookieHandler.setDefault(new CookieManager())
自动处理会话 cookie,这工作正常。
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.
在登录后的某个时刻,我想向用户显示来自 Web 应用程序的实时页面,WebView
而不是使用HttpURLConnection
. 但是,我想使用我之前建立的同一个会话来防止用户再次登录。
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?
如何将 cookie 从java.net.CookieManager
used by复制HttpURLConnection
到android.webkit.CookieManager
used byWebView
以便我可以共享会话?
采纳答案by quietmint
As compared with DefaultHttpClient
, there are a few extra steps. The key difference is how to access the existing cookies in HTTPURLConnection
:
与 相比DefaultHttpClient
,有一些额外的步骤。主要区别在于如何访问 中的现有 cookie HTTPURLConnection
:
- Call
CookieHandler.getDefault()
and cast the result tojava.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 givenURI
.
- 调用
CookieHandler.getDefault()
并将结果转换为java.net.CookieManager
. - 使用 cookie 管理器,调用
getCookieStore()
访问 cookie 存储。 - 使用 cookie 存储,调用
get()
以访问给定 的 cookie 列表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<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
...
}
回答by talkol
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 samecookie storage.
我想建议一种完全不同的方法来解决您的问题。与其将 cookie 从一处复制到另一处(手动同步),不如让 HttpURLConnection 和 WebViews 使用相同的cookie 存储。
This completely eliminates the need for sync. Any cookie updated in any one of them, will be immediately and automatically reflected in the other.
这完全消除了同步的需要。在其中任何一个中更新的任何 cookie 将立即并自动反映在另一个中。
To do this, create your own implementation of java.net.CookieManager which forwards all requests to the WebViews' webkit android.webkit.CookieManager.
为此,创建您自己的 java.net.CookieManager 实现,它将所有请求转发到 WebView 的 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<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();
}
}
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);
回答by Chani
I magically solved all my cookie problems with this one line in onCreate:
我用 onCreate 中的这一行神奇地解决了我所有的 cookie 问题:
CookieHandler.setDefault(new CookieManager());
CookieHandler.setDefault(new CookieManager());
回答by Christian
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 :
在登录后(这很重要,因为之前,您可能还没有 cookie)使用 httpurlconnection POST(在 getResponseCode 之后),我这样做:
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)
(其中 cookie 是我班级中的公共字符串)
And in the webview activity, where I want to display a web page from server using WebView, I do :
在 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();
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).
由于我的 webview 在一个片段中,我必须使用 getActivity() 作为上下文,我还必须指定 android.webkit。在 CookieManager 之前,否则无法解析(导入 java.net 而不是 android.webkit cookie manager)。
cookie is the same String as above (in my Fragment, I had to recover it using :
cookie 与上述字符串相同(在我的 Fragment 中,我必须使用以下方法恢复它:
cookie = getArguments().getString(COOKIE);
and in my MainActivity, I send it by :
在我的 MainActivity 中,我通过以下方式发送它:
Bundle arg = new Bundle();
arg.putString(Fragment_Cameras.COOKIE, cookie);
fragment.setArguments(arg);
I hop this can help !
我希望这会有所帮助!