How to handle cookies in httpUrlConnection using cookieManager
Ok, the right way to do it is just like that:
Get Cookies from response header and load them into cookieManager:
static final String COOKIES_HEADER = "Set-Cookie";
HttpURLConnection connection = ... ;
static java.net.CookieManager msCookieManager = new java.net.CookieManager();
Map<String, List<String>> headerFields = connection.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if (cookiesHeader != null) {
for (String cookie : cookiesHeader) {
msCookieManager.getCookieStore().add(null,HttpCookie.parse(cookie).get(0));
}
}
Get Cookies from cookieManager and load them into connection:
if (msCookieManager.getCookieStore().getCookies().size() > 0) {
// While joining the Cookies, use ',' or ';' as needed. Most of the servers are using ';'
connection.setRequestProperty("Cookie",
TextUtils.join(";", msCookieManager.getCookieStore().getCookies()));
}
Should HttpURLConnection with CookieManager automatically handle session cookies?
I run your code and replace this
CookieHandler.setDefault(new CookieManager());
by
CookieHandler.setDefault( new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );
It work!
Pass cookies from HttpURLConnection (java.net.CookieManager) to WebView (android.webkit.CookieManager)
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 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
.
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
...
}
Cookie management with Java URLConnection
You need to maintain your cookie context external to each call and provide the same cookie store it on subsequent GETs and POSTs. This is the same for both the Java implementation and Apache's implementation.
In my experience, Apache's HTTP components is better than the built in Java implementation. I spent a large amount of time trying to write a utility using Java's implementation, my largest problem was timeouts. Bad web servers would hang causing the connection to hang indefinitely. After switching to Apache the timeouts were tuneable and we didn't have any more hung threads.
I'll give an example using Apache.
Create the CookieStore
instance in your parent method:
CookieStore cookieStore = new BasicCookieStore();
Then in your GET or POST implementations pass in the CookieStore
instance and use it when you build the HttpClient:
public void sendGet(String url, CookieStore cookieStore) throws Exception {
...
HttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
HttpGet request = new HttpGet(uri); // or HttpPost...
request.addHeader("User-Agent", USER_AGENT);
HttpResponse response = client.execute(request);
BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
...
}
Android has extended java.net.HttpURLConnection
and recommends using this, so I'll also give an outline for that as well.
HttpURLConnection
and HttpsURLConnection
automatically and transparently uses the CookieManager
set in CookieHandler
. CookieHandler
is VM-wide so must be setup only once. If you create a new CookieManager
for each request, as you did in your code, it will wipe out any cookies set in previous requests.
You do not need to create an instance of HttpCookie
yourself. When HttpURLConnection
receives a cookie from the server the CookieManager
will receive the cookie and store it. Future requests to the same server will automatically send the previously set cookies.
So, move this code to your application setup so it happens only once:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
URLConnection with Cookies?
I was able to enable cookies using Ian Brown's CookieManager class:
http://www.hccp.org/java-net-cookie-how-to.html
I renamed it to IansCookieManager, set a class variable _CM = new IansCookieManager, now it's simple:
URLConnection conn = u.openConnection();
_CM.setCookies(conn);
conn.connect();
_CM.storeCookies(conn);
...
Related Topics
Android Background Image Size in Pixel
Filtering Listview with Custom (Object) Adapter
Transitive Dependencies for Local Aar Library
Android - Local Image in Webview
Android Get Image from Gallery into Imageview
Sqliteopenhelper Problem with Fully Qualified Db Path Name
Remove Listview Items in Android
How to Request Permissions from a Service in Android Marshmallow
How to Create Edittext Accepts Alphabets Only in Android
How to Display Album Art Using Mediastore.Audio.Albums.Album_Art
Detecting Whether a Headset Is Plugged into an Android Device or Not
Adt Will Not Allow Creation of Android Activity
Java.Lang.Classnotfoundexception on Working App
Java.Lang.Illegalargumentexception: Contains a Path Separator
Cannot Load Library: Reloc_Library[1285]: Cannot Locate 'Rand'
Blue Dot and Circle Is Not Shown on Mylocation Using Android Fused Location API
How to Create a Signed APK File Using Cordova Command Line Interface