Cookie management and saving state in Android apps.

I just wrote my first Android app using the ADT plugin for Eclipse. This particular app I wrote interacts with existing web services we deployed on our main production servers. I was having the hardest time maintaining a session state during web service calls on the back-end. All I needed was the following one line of code in my onCreate function of the Activity which calls the web service that sets up the session:

CookieHandler.setDefault(new CookieManager( null, CookiePolicy.ACCEPT_ALL));

Presto! State saved across all subsequent web service calls.

JSON-ing and request headers

We have this web widget that calls a particular webservice and does a JSON post. This was failing miserably on the back-end. For some reason, the data that was ending up in the session was not ending up in $session->params->{POSTDATA} but instead $session->params->{keywords}. In turn, our webservice was bombing when it was trying to access the data from POSTDATA since it wasn’t there in the session. Here’s an excerpt of the Perl data dump for the bad session:

_QUERY       => bless({
                      ".charset"     => "ISO-8859-1",
                      ".cookies"     => {
                                          sid => bless({
                                                   name  => "sid",
                                                   path  => "/",
                                                   value => ["XXXXXXXXXXXXXXXXXXXXX"],
                                                 }, "CGI::Cookie"),
                                        },
                      ".fieldnames"  => {},
                      ".parameters"  => ["keywords"],
                      "escape"       => 1,
                      "param"        => {
                                          keywords => [
                                            "{\"fname\":\"Steve\",\"lname\":\"Dickinson\",\"phone\":\"5557771000\",\"email\":\"steve\@someplace.com\",\"date\":\"2014-07-05\",\"time\":\"18:00:00\",\"size\":2,\"notes\":\"notes\"}",
                                          ],
                                        },
                      "use_tempfile" => 1,
                    }, "CGI"),
    _STATUS      => 5,
  }, "CGI::Session");

It should have instead looked like this:

_QUERY       => bless({
                      ".charset"     => "ISO-8859-1",
                      ".cookies"     => {
                                          sid => bless({
                                                   name  => "sid",
                                                   path  => "/",
                                                   value => ["XXXXXXXXXXXXXXXXXXXXX"],
                                                 }, "CGI::Cookie"),
                                        },
                      ".fieldnames"  => {},
                      ".parameters"  => ["keywords"],
                      "escape"       => 1,
                      "param"        => {
                                          POSTDATA => [
                                            "{\"fname\":\"Steve\",\"lname\":\"Dickinson\",\"phone\":\"5557771000\",\"email\":\"steve\@someplace.com\",\"date\":\"2014-07-05\",\"time\":\"18:00:00\",\"size\":2,\"notes\":\"notes\"}",
                                          ],
                                        },
                      "use_tempfile" => 1,
                    }, "CGI"),
    _STATUS      => 5,
  }, "CGI::Session");

During this time I was also building a similar Android app to mimic how this widget works. The funny thing was, that the Android app worked but the widget didn’t. In thinking back to my app code I soon realized the issue. In the app code I had correctly set the header like so:

httppost.setHeader("Accept", "application/json");
httppost.setHeader("Content-type", "application/json");

The widget had no such code for this webservice call. So I added the following handleAs & headers definitions to the developer’s JavaScript code:

var req = {
    data: JSON.stringify(requestData),
        handleAs: 'json',
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
            }
    };
request.post('http://somedomain.com/webservice_call', req).then(

That’s all it took!