Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I persist cookies when using HTTPUrlConnection?

I've begun using the recommended HTTPUrlConnection and moved away from the DefaultHTTPClient. One of the things that I haven't been able to glue back together is the use of a persistent cookie store. I'd like to simply attach a custom cookie handler/manager to my connection to store the cookies. The Android documentation hasn't been very helpful as it wraps up the subject about cookies in two lines.

I've been using LoopJ's PersistentCookieStore earlier and that worked beautifully.

Any idea on how I could set up a persistent cookie store in Android that I can attach to my HTTPUrlConnection that saves and retrieves cookies automatically?

Thanks

like image 1000
Mridang Agarwalla Avatar asked Sep 10 '12 09:09

Mridang Agarwalla


People also ask

How do I set cookies in Httpurlconnection?

openConnection(); Create a cookie string: String myCookie = "userId=igbrown"; Add the cookie to a request: Using the setRequestProperty(String name, String value); method, we will add a property named "Cookie", passing the cookie string created in the previous step as the property value.

How do I get Httpurlconnection cookies?

Retrieving CookiesCreate an instance of the CookieManager class and set its CookiePolicy . Set this instance of the CookieManager as the default CookieHandler . Open a URLConnection to the website of your choice. Next, retrieve cookies from the underlying CookieStore by using the getCookies method.

What is Cookie Manager in Java?

CookieManager provides a concrete implementation of CookieHandler , which separates the storage of cookies from the policy surrounding accepting and rejecting cookies.


3 Answers

Its' taken me a few hours but I managed to build a custom cookie storage myself.

You have to attach this by doing this:

public class application extends Application {     @Override     public void onCreate() {         super.onCreate();        CookieManager cmrCookieMan = new CookieManager(new MyCookieStore(this.objContext), CookiePolicy.ACCEPT_ALL);        CookieHandler.setDefault(cmrCookieMan);        }     } 

Here's the actual storage:

/*  * This is a custom cookie storage for the application. This  * will store all the cookies to the shared preferences so that it persists  * across application restarts.  */ class MyCookieStore implements CookieStore {      /*      * The memory storage of the cookies      */     private Map<URI, List<HttpCookie>> mapCookies = new HashMap<URI, List<HttpCookie>>();     /*      * The instance of the shared preferences      */     private final SharedPreferences spePreferences;      /*      * @see java.net.CookieStore#add(java.net.URI, java.net.HttpCookie)      */     public void add(URI uri, HttpCookie cookie) {          System.out.println("add");         System.out.println(cookie.toString());          List<HttpCookie> cookies = mapCookies.get(uri);         if (cookies == null) {             cookies = new ArrayList<HttpCookie>();             mapCookies.put(uri, cookies);         }         cookies.add(cookie);          Editor ediWriter = spePreferences.edit();         HashSet<String> setCookies = new HashSet<String>();         setCookies.add(cookie.toString());         ediWriter.putStringSet(uri.toString(), spePreferences.getStringSet(uri.toString(), setCookies));         ediWriter.commit();      }     /*     * Constructor     *      * @param  ctxContext the context of the Activity     */     @SuppressWarnings("unchecked")     public MyCookieStore(Context ctxContext) {          spePreferences = ctxContext.getSharedPreferences("CookiePrefsFile", 0);         Map<String, ?> prefsMap = spePreferences.getAll();          for(Map.Entry<String, ?> entry : prefsMap.entrySet()) {              for (String strCookie : (HashSet<String>) entry.getValue()) {                  if (!mapCookies.containsKey(entry.getKey())) {                      List<HttpCookie> lstCookies = new ArrayList<HttpCookie>();                     lstCookies.addAll(HttpCookie.parse(strCookie));                      try {                          mapCookies.put(new URI(entry.getKey()), lstCookies);                      } catch (URISyntaxException e) {                          e.printStackTrace();                      }                  } else {                      List<HttpCookie> lstCookies = mapCookies.get(entry.getKey());                     lstCookies.addAll(HttpCookie.parse(strCookie));                      try {                          mapCookies.put(new URI(entry.getKey()), lstCookies);                      } catch (URISyntaxException e) {                          e.printStackTrace();                      }                  }                  System.out.println(entry.getKey() + ": " + strCookie);              }          }      }      /*      * @see java.net.CookieStore#get(java.net.URI)      */     public List<HttpCookie> get(URI uri) {          List<HttpCookie> lstCookies = mapCookies.get(uri);          if (lstCookies == null)             mapCookies.put(uri, new ArrayList<HttpCookie>());          return mapCookies.get(uri);      }      /*      * @see java.net.CookieStore#removeAll()      */     public boolean removeAll() {          mapCookies.clear();         return true;      }              /*      * @see java.net.CookieStore#getCookies()      */     public List<HttpCookie> getCookies() {          Collection<List<HttpCookie>> values = mapCookies.values();          List<HttpCookie> result = new ArrayList<HttpCookie>();         for (List<HttpCookie> value : values) {                             result.addAll(value);                         }          return result;      }      /*      * @see java.net.CookieStore#getURIs()      */     public List<URI> getURIs() {          Set<URI> keys = mapCookies.keySet();         return new ArrayList<URI>(keys);      }      /*      * @see java.net.CookieStore#remove(java.net.URI, java.net.HttpCookie)      */     public boolean remove(URI uri, HttpCookie cookie) {          List<HttpCookie> lstCookies = mapCookies.get(uri);          if (lstCookies == null)             return false;          return lstCookies.remove(cookie);      }  } 
like image 153
Mridang Agarwalla Avatar answered Sep 21 '22 08:09

Mridang Agarwalla


I used the answer above but changed my add method to the following to handle more than one cookie from the same URI (this cookie store with GAE was treating the session token and the remember token as two separate cookies from the same URI for some reason):

public void add(URI uri, HttpCookie cookie) {


    List<HttpCookie> cookies = mapCookies.get(uri);
    if (cookies == null) {
        cookies = new ArrayList<HttpCookie>();
        mapCookies.put(uri, cookies);
    }
    cookies.add(cookie);

    Editor ediWriter = spePreferences.edit();
    HashSet<String> setCookies = new HashSet<String>();
    setCookies.add(cookie.toString());
    HashSet<String> emptyCookieSet = new HashSet<String>();
    if(spePreferences.contains(uri.toString())){
        emptyCookieSet = (HashSet<String>) spePreferences.getStringSet(uri.toString(), emptyCookieSet);
        if(!emptyCookieSet.isEmpty()){
            if(!emptyCookieSet.contains(cookie.toString())){
            emptyCookieSet.add(cookie.toString());
            ediWriter.putStringSet(uri.toString(), emptyCookieSet);
            }
        }
    }
    else{
        ediWriter.putStringSet(uri.toString(), setCookies);
    }
    ediWriter.commit();
} 

And to access and create a combined cookie:

MyCookieStore store = new MyCookieStore(this.context, false);
String cookie = TextUtils.join(",", store.get(new URI(URLString)));

Attach to connection:

URL urlToRequest = new URL(stringPath);
HttpURLConnection urlConnection = (HttpURLConnection) urlToRequest.openConnection();
urlConnection.setRequestProperty("Cookie", cookie); 
like image 37
StiggyBr0 Avatar answered Sep 19 '22 08:09

StiggyBr0


Checkout the implementation in the link below. It saves the cookies by hostname like the original java.net.InMemoryCookieStore implementation does.

Besides that it contains a SerializableHttpCookie to be able to serialize the complete HashMap into the SharedPreferences.

https://gist.github.com/jacobtabak/78e226673d5a6a4c4367

like image 45
Ben Groot Avatar answered Sep 21 '22 08:09

Ben Groot