We have an Android application that requires the user to enter an answer to a Captcha. The Captcha is generated on our server. When the replies, it is sent to the server for verifying.
Problem is that since I have to close the HttpURLConnection after the request for the Captcha I then find that the reply is running on a different session on the sever. Because of this the Captcha check fails since it is session dependant.
Is there a way to keep the connection alive or should I be following a different path? I know that in the equivalent iPhone application they remain "connected" and thus have the same sessionid.
Edit:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
URL urlObj = new URL(urlPath);
conn = (HttpURLConnection) urlObj.openConnection();
if (urlPath.toLowerCase().startsWith("https:")) {
initializeHttpsConnection((HttpsURLConnection) conn);
}
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Language", "en-US");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(bodyData.length));
if (_sessionIdCookie != null) {
conn.setRequestProperty("Cookie", _sessionIdCookie);
}
// Connect
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
You don't. You close this one and create a new one.
Yes you need to close the inputstream first and close httpconnection next. As per javadoc.
Deprecated. it is misplaced and shouldn't have existed. HTTP Status-Code 401: Unauthorized. HTTP Status-Code 503: Service Unavailable.
URLConnection is the base class. HttpURLConnection is a derived class which you can use when you need the extra API and you are dealing with HTTP or HTTPS only. HttpsURLConnection is a 'more derived' class which you can use when you need the 'more extra' API and you are dealing with HTTPS only.
To maintain session using HttpURLConnection
you need to execute this part
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
only once and not on every connection. Good candidate can be on application launch inside Application.onCreate();
Normally, sessions are not kept based on the http connection itself. That wouldn't make any sense. Sessions are normally kept alive through a cookie on the client side and session information on the server side. What you gotta do is save the cookie(s) you're receiving and then setting that(those) cookie(s) next time you connect to the server.
To learn more about how to work with sessions and cookies with the HttpUrlConnection class, read the documentation: http://developer.android.com/reference/java/net/HttpURLConnection.html
Here a little excerpt to get you started:
To establish and maintain a potentially long-lived session between client and server, HttpURLConnection includes an extensible cookie manager. Enable VM-wide cookie management using CookieHandler and CookieManager:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
EDIT:
For those working with API levels 8 or lower, you'll need to use Apache's library!
Here's some reference code:
// Create a local instance of cookie store
CookieStore cookieStore = new BasicCookieStore();
// Create local HTTP context
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet httpget = new HttpGet("http://www.google.com/");
System.out.println("executing request " + httpget.getURI());
// Pass local context as a parameter
HttpResponse response = httpclient.execute(httpget, localContext);
The code above was taken from the Apache's library examples. It can be found here: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomContext.java
EDIT 2: Making it clear:
For the Apache library you need to somehow "connect" the cookie management object with the connection object and you do that through the HttpContext object.
In HttpUrlConnection's case that's not necessary. when you use CookieHandler's static method setDefault, you're setting the system-wide cookieHandler. Below is an excerpt from CookieHandler.java. Note the variable name (from the Android Open Source Project's (AOSP) repository):
37 /**
38 * Sets the system-wide cookie handler.
39 */
40 public static void setDefault(CookieHandler cHandler) {
41 systemWideCookieHandler = cHandler;
42 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With