Reputation: 851
I'm fairly new to android programming and recently achieved a successful HTTP Post request, only to learn that my cookies are not being stored between subsequent Post/Get requests. I looked around the interweb, and found a few examples for Android's Apache client and Java's HttpURLConnection. I was unsuccessful in implementing either method into my current class, so I was wondering if someone with more experience could review my code and offer suggestions.
Recap:
Any help is appreciated, thank you.
webCreate.java
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class webCreate {
private final String USER_AGENT = "Mozilla/5.0";
// HTTP GET request
public void sendGet(String url) throws Exception {
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
HttpCookie cookie = new HttpCookie("lang", "en");
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
Log.d("sendGet", "\nSending 'GET' request to URL : " + url);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
Log.d("Response Code", response.toString());
}
// HTTP POST request
String sendPost(String url, String urlParams) throws Exception {
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
HttpCookie cookie = new HttpCookie("lang", "en");
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add request header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParams);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("Response Code : " + response);
return response.toString();
}
}
Upvotes: 2
Views: 5905
Reputation: 668
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);
Upvotes: 6