Making a POST request in an Android app (and why I hate Java)

As anyone who's read my past post on context switching knows, my most recent project - Backstep - is being built with a combination of technologies including Python/Django and Java/Android. Similar to my previous experiences with it, Python is a pleasure to use. It's super expressive, has a knowledgeable and friendly community, and a library exists for just about any domain one might encounter. But Java. Java is a different story. Similar to my past experiences with that language, usage feels akin to diving into the Mariana trench with one of these bad boys:
diving suit

The language feels archaic, clunky, and rather like a straitjacket, unecessarily inhibiting my creativity rather then enabling it. As in life, though, sometimes we are forced to do things (or use things) we would prefer to avoid. And so, in this post I'll lay out how to make a POST request with Java (Hint: it's nowhere near as straightforward as the ubiquitous requests library for Python)


First, let's examine a POST request using a brilliant request library.

import requests
import json

res = requests.post(
    'http://some_url.com/api/',
    json.dumps({'some_request_param': 'yay value'})
)

Its syntactically and semantically easy on the eyes (and fingers), yet flexible enough to work for nearly all use cases. Now onto its Frankenstein's monster equivalent in Java.


Before laying out the Java equivalent POST request, I should mention that the library I decided to use for crafting the requests was the best that I found for my purposes, but might not be the best for everyone / for all use cases. So use at your own discretion.

All disclaimers aside, let's hook up the electrodes and bring our monster to life. First, we add the required dependencies to Gradle (or Maven if that's what you're into, Android recommends Gradle, however). We're going to need both Jackson (or some other JSON object mapper) as well as a request library. For Backstep, I went with the Java http-request library by Kevin Sawicki to fill this requirement. So at this point, our build.gradle file should have the following dependencies specified.

dependencies {
  compile 'com.github.kevinsawicki:http-request:5.6'
  compile 'com.fasterxml.jackson.core:jackson-databind:2.3.0'
  ...
}

Notice that I used the com.fasterxml.jackson library rather then the library located at the Jackson URL specified above. All you need to know is that this isn't necessary, just include Jackson in your dependencies.

Next, we create a subclass of Android's AsyncTask for our POST request. Mine looks like this:
post class

A couple things to notice here.

  • mapper.writeValueAsString(this.instance) is the line that actually serializes an object to JSON.
  • My subclass is abstract. The reasoning behind this is that for any given POST request, I'm probably going to want a different callback for onPostExecute.
  • The subclass is parameterized. This gives me the ability to craft a POST request for any serializable object.

Now to raise the platform and apply the lightning for jump starting our monstrosity. We must define a class representing the entity we wish to POST. For this, Jackson has a template which you should follow and basically just requires specifying fields, getters, and setters. Here is one such entity in my system.
api entity

The monster is beginning to show signs of life. His green skin is glowing faintly and his chest heaving up and down. Unfortunately, he's still very much useless. The next step in creating our request is building a concrete subclass of our PostApi. This subclass's only requirement is to implement the abstract method defined in its parent, onPostExecute. For our City example, it might look something like this:

private class CityPost extends PostApi<City> {
    protected CityPost(City c) {
        super('endpoint_to_post_to', c);
    }

    protected void onPostExecute(Map<String, ?> response) {
        //do some stuff with the response
    }
}

It's alive! It's alive!! We're ready to make our request! Thankfully this part is the easiest and simply requires instantiating and executing our CityPost. The code to do so is simply

new CityPost(city_instance).execute();

Ahh so, Java, let's talk. I know that enterprises use you. I know that you have a runtime environment that's deployable to nearly (if not every) platform. I know that you're modular, scalable, and bloated with features. But I don't like you. I don't like that it takes me more then triple the lines to perform the same tasks when compared to Python or Javascript. I don't like your stringent type system, causing me compile-time headaches I'd much rather address at run-time. And I don't like your disregard for coding beauty (using Python - again - as the golden standard).


With the wise words of Sterling Archer as motivation, I leave you to go and try building your very own POST request in Java.

Archer - Cry havoc and let slip the hogs of war.
Lana - Dogs
Archer - Whatever farm animal of war, Lana! Shut up!