The Reason The Internet Was Invented, or, Cat Pictures FTW

I’ll report about the SpringOne2GX conference soon, but I’m fighting a cold at the moment and the medication has put me in a rather bleary state. Thus, the following bit of random Groovy whimsy…

In this post, I’ll use Groovy to access a publicly available RESTful web service, parse the downloaded data, and build a GUI to hold the resulting images. The code will demonstrate the Groovy JDK, maps, the collect method, I/O processing, and the builder pattern, all to achieve its ultimate goal: looking at cat pictures.

A Flickring Light In The Darkness

There are many so-called RESTful web services available to the general public. Despite the name, however, most only support GET requests. This isn’t terribly surprising, since POST, PUT, and DELETE would require some kind of transaction, and security, and all sorts of protection against the sort of damage reminiscent of YouTube comments[1].

Examples of that sort of services include Open Weather Map (http://openweathermap.org/api), Currency Exchange Rates (http://openexchangerates.org), the Bing[2] Maps REST services (http://msdn.microsoft.com/en-us/library/ff701713.aspx), the Google Maps Geocoder (https://developers.google.com/maps/documentation/geocoding/) and the source for this article, Flickr (https://secure.flickr.com/services/developer). Each supports HTTP GET requests only.

If a RESTful web service only supports GET requests, does that make it a GETful service? If so, and it’s also stateless, does that make it a FORGETful web service? Thank you, thank you. Try the veal, and please remember to tip your wait staff.

Believe it or not, Flickr used to be the definitive site for image sharing, and some people still use it. Access requires a key, which means you need to register with Yahoo!, another web site that used to matter long, long ago when the web was shiny and new.

Why use it here? It’s available, it’s free, and, most important of all, it’s got cat pictures.

Feeling Groovy

Groovy is one of the new family of languages that compiles to bytecodes for the Java Virtual Machine. It’s simpler than Java, yet much more powerful, and has an easy learning curve for existing Java developers. It’s cool in its own right, and also forms the basis of interesting projects like Grails and Gradle.

Hey, I even wrote a Java/Groovy integration book about it.

Now on to the Groovy. Let’s assume you register and receive your special key. Save it in a file called flickr_key.txt, so you can access it this way:

String key = new File('flickr_key.txt').text

Accessing a property (like text here) in Groovy is the same as invoking the corresponding getter or setter method. Here, the Groovy JDK adds the getText method to File, which returns the contents of the file.

The base URL for the web service is:

String endPoint = 'https://api.flickr.com/services/rest?'

I included the “?” because I want to append the generated query string to the end point to get the complete URL.

The Flickr API uses a query string with a lot of parameters. Here I add them to a Groovy map.

def params = [method: 'flickr.photos.search', api_key: key,
    format: 'json', tags: 'cat', nojsoncallback: 1,
    media: 'photos', per_page: 6]

I’m calling the flickr.photos.search method with the api_key. I want JSON data back, but not as a JSON callback, and I want photo data using the cat tag. It’s not terribly complicated, but there are a lot of parameters.

The cool part is that a Groovy map like this can be converted to a query string using a very common idiom. The collect method applied to a map generates a list by applying a closure to each element of the original list. Therefore I can generate the query string thusly:

def qs = params.collect { k,v -> "$k=$v" }.join('&')

The two-argument closure takes each key/value pair and returns a string where the key equals the value. Then the join method applied to the list creates a string whose entries are separated by ampersands.

That means the whole URL is defined by "$endPoint$qs". I can then use the toURL method from the Groovy JDK to convert the string to a URL[3], and the text parameter invokes getText, returning the total response.

I can now use the cool JsonOutput.prettyPrint(txt) method to format the output and write it to a file.

File f = new File('cats.json')
if (f) f.delete()
f << jsonTxt
println JsonOutput.prettyPrint(jsonTxt)

Here’s a sample from that output:

{
    "photos": {
        "page": 1,
        "pages": 882777,
        "perpage": 6,
        "total": "5296661",
        "photo": [
            {
                "id": "15077663928",
                "owner": "125421155@N06",
                "secret": "dc605f2671",
                "server": "3837",
                "farm": 4,
                "title": "Mornings with bb kitty",
                "ispublic": 1,
                "isfriend": 0,
                "isfamily": 0
            },
            { ... },
            { ... },
            { ... },
            { ... },
            { ... }
        ]
    },
    "stat": "ok"
}

From JSON to Cat Pictures

Each photo block has the components necessary to assemble the URL to retrieve it, which is way more complicated than it needs to be but is still doable. Here’s the code for that part.

def json = new JsonSlurper().parseText(jsonTxt)
def urls = json.photos.photo.collect { p ->
    "http://farm${p.farm}.staticflickr.com/${p.server}/${p.id}_${p.secret}.jpg"
}

The JsonSlurper has a parseText method that converts the received JSON string into a Groovy map. Then walking the map by calling json.photos.photo gets all the photo objects, and the collect block converts each of them into a URL.

All that remains is to access all the photo URLs and populate a simple GUI with them. One simple way to do that is to use Groovy’s SwingBuilder class.

new SwingBuilder().edt {
    frame(title:'Cat pictures', visible: true, pack: true,
        defaultCloseOperation: WindowConstants.EXIT_ON_CLOSE,
        layout:new GridLayout(0, 2)) {
        urls[0..5].each { String url ->
            label(icon:new ImageIcon(url.toURL()))
        }
    }
}

The SwingBuilder has an edt method, which builds the UI on the event dispatch thread. The frame “method” instantiates a JFrame with the given title, makes it visible, and packs it as small as possible. The GUI uses a GridLayout to make two columns of equally-spaced elements, each of which is a JLabel that contains an ImageIcon with the individual photo URLs.

The result is a display of the most recent six pictures tagged cat in Flickr, which can result in almost anything[4].

Here’s a sample view:

Cat-pictures

Don’t ask me about the monkey. I have no idea what that’s about either.

So what have we learned?

  1. Groovy maps can be converted to query strings using a closure and the join method
  2. The Groovy JDK adds methods to Java library classes that you wished were there all along
  3. Groovy builders can make Swing programming almost, but not quite, pretty cool
  4. I can haz kitteh pics

The entire script from this article is part of a GitHub repository called IntroGroovy. Drill down to the src/main/groovy/flickr directory. You’ll need to add your own Flickr key, but after that, go for it. Just don’t be surprised, apparently, if you get monkeys or tractors mixed in with your cat pictures.

I suppose now I should go and reimplement the whole script in LOLCODE.


1. Okay, that’s a little harsh. Nothing could be as awful as YouTube comments. Or perhaps the correct response to that is, “I didn’t know YouTube supported comments.” If that’s your answer, I SO wish I was you.
2. Come on, stop laughing. I get it: “If you don’t remember what Bing is, just Google it”. Ha ha.
3. What did you expect toURL to convert the string into, a tomato? That would be pretty cool, actually. Now I wish I had that method. Of course, Groovy is an open source project…​
4. Usually it’s cats, but once I got a bunch of tractors, which confused me until I realized they were manufactured by Caterpillar.

SpringOne2GX, Day Minus 3

Yes, that’s a minus sign, because the event in question hasn’t happened yet. This is my first report from the upcoming SpringOne2GX conference, which starts in Dallas, TX next Monday, 9/8/14 (or 8/9/14 for my non-US-based friends). Since there are no talks on the opening day (just an opening keynote and reception), I’m arbitrarily designating that as Day Zero. I’m giving several talks at the conference and I thought I’d comment here on my preparations. I also have a kind of “insider” status, being a member of the No Fluff, Just Stuff conference tour (one of the organizers of SpringOne2GX*) and, as the author of Making Java Groovy, I know a lot of people in the community. That will hopefully give me opportunities to share amusing anecdotes and other non-presentation-based tidbits of information here.

*What is the proper hashtag for the conference? In past years people have recommended #springone2gx, but that’s way too many characters. The value #s12gx seems reasonable, but didn’t seem to catch on. Most people I know used #s2gx, which is probably what I’ll adopt.

Speaking of embarrassing anecdotes, let me give you one right away. Two years ago, after one of my talks at that year’s s2gx conference, Guillaume Laforge and Cedric Champeau came up to me to say hi. Guillaume, who lives near Paris, has an outrageous French accent. Every time I talk to him I keep thinking of this character from the classic movie. So I finally got up the nerve to ask him, “Just once, would you say to me, ‘your mother was a hamster, and your father smelt of elderberries!'”.

He and Cedric both just stared at me like I’d lost my mind. They had no idea what I was talking about. It wasn’t until later I realized that even if they knew Monty Python and the Holy Grail (a minimum requirement for any decent developer), they knew it in French.

Oh well.

This week I’m still polishing (yeah, right, polishing — not writing from scratch, at least as far as you know) my slides. I’m scheduled to give the following talks:

This is an introduction to Grails, combining domain classes (of course, Quest, Task, Knight, and Castle), controllers, services (using the Google geocoder), and more. Experienced Grails developers can comfortably skip it, but newbies will no doubt appreciate the introduction. I plan to add in some architectural discussions, as well as some Hibernate and/or Spring stuff if time allows.

I gave a similar talk a couple years ago, but things have changed significantly since then. As a minimal example, now the default unit testing framework is Spock, rather than the JUnit subclasses we used to use. Everything is annotation based, too. I’ll definitely talk about testing controllers, services, and domain classes (constraints), and plan to do a couple of integration tests as well, and then talk about various plugins, like the Build Test Data plugin and some other functional ones.

As I travel from company to company*, I rarely see the new REST capabilities in Grails 2.3+ being used. Last year Graeme Rocher did a wonderful presentation on them, as well as a brief discussion of the asynchronous capabilities in Grails. I hope to cover much the same (REST) ground, but rather than get into async I’m going to talk about customizing responses, using HAL for hypermedia, and so on.

*My day job is teaching technical training courses in pretty much all areas related to Java, specializing in open source topics like Spring, Hibernate/JPA, Android, Groovy, and Grails. That means I visit somewhere between 30 to 50 companies a year, and while I’m mostly talking to people who don’t know much about Grails yet, I’m always trying to find out what they are using. Between that and the NFJS conferences, I get a decent sense of what is becoming popular in the industry and what isn’t catching on.

As a sample, both Groovy and Grails are still growing at their normal slow, steady pace. Spring Boot is generating a lot of excitement among the more advanced developers, but most Spring users in the field haven’t even heard of it. I imagine this year’s conference will start to change that.

It turns out that Jeff Brown (co-author of DGG2, the Definitive Guide to Grails 2) is giving a talk entitled RESTful Grails 2 at 12:45pm on Tuesday. This is extraordinarily fortunate for me, because that means I can steal (er, reuse) whatever he says. Sweet. 🙂

I gave a similar talk last year, and was just getting ready when Paul King walked into the room. Paul King is one of the Greatest Groovy Experts Ever, and I experienced a flood of Imposter Syndrome as soon as he entered. Fortunately, he didn’t violently disagree with anything I said and was kind enough to share some additional information after it was over. Is it any wonder he is one of my personal heroes?

Another interesting Paul King tidbit: last time I checked, he had more commits to the Groovy code base than anyone, ever. Heck, I just checked and he did six more today.

I’ve updated the talk with new information, which should be fun. The toughest problem I’ll have is not giving away spoilers for the Groovy Puzzlers talk coming later in the conference.

(Go to the puzzlers talk. It’s fun.)

This is a big one for me. The fact that Android applications are now built using Gradle is a big deal for every Android developer, and the Android plugin for Gradle is still evolving at a rapid rate. The new IDE, Android Studio, is also changing all the time. My hope is to give the most up-to-date information on it possible. I’ll show the multi-project build they use by default, add some dependencies, run some tests (using the Robotium plugin), talk about Spring Android, and show some flavors and variants.

Best of all, I expect to try to update Android Studio right before the talk, so I have the latest possible version in the so-called Canary channel. What could possibly go wrong?

This is a revised and extended version of the same talk I gave at the Gr8 conf in Minneapolis in July. Those talks were limited to an hour, and given that lots of speakers were talking about Ratpack*, I decided to focus on Grails for the REST part. Now I should have time for both.

*Dan “Tiger” Woods is giving his Ratpack Web Framework talk at 2:30pm on Tuesday.

Wait, let’s try to improve that:

['Tiger','James','Ickey','Mirk','Sher'].each { nickname ->
    println "Dan '${nickname}' Woods"
}

Let me know if you have some better suggestions. Also, Lari Hotari is giving a talk on Ratpack and Grails 3.

Since there are no images in this post, here’s a small spoiler from the Groovy Vampires talk. Note the nice subtitle.

Making Java Groovy: Still a better love story than Twilight

If you’re coming to the conference, please drop by and say hi. I hope to write a short blog post every day of the conference, commenting on what talks I attended and which people I spoke to, but that’ll depend on how much last minute “updating” I’ll need to do on my slides.

%d bloggers like this: