Converting Groovy maps to query strings - No Fluff Just Stuff

Converting Groovy maps to query strings

Posted by: Kenneth Kousen on November 2, 2011

Yesterday I was teaching a class on Groovy when I suddenly realized there was a simpler way to do something I’d been doing for years.

I like showing developers how easy it is to access RESTful web services with just a couple of lines of Groovy. The process is particularly simple if all you need is a GET request, since you can just convert a String to a URL and use the getText method to retrieve the response.

For example, consider the Google Chart Tools service. The idea there is that you can send your data in a URL to Google and the service will return a graphical image of the data. The “Hello, World!” example from the documentation looks like

https://chart.googleapis.com/chart?chs=250x100&chd=t:60,40&cht=p3&chl=Hello|World

There is a base URL (https://chart.googleapis.com/chart) followed by a query string with lots of parameters. In this particular case, the parameters are chs (the chart size, 250×100 pixels), chd (chart data, here 60 and 40), cht (the chart type, here a 3D pie chart), and chl (the chart labels, “Hello” and “World” separated by vertical bars). If you transmit this URL to Google, it will respond with a nice image.

It’s easiest to see that by simply embedding the URL as the href attribute of an <img> tag.

From a Groovy point of view, the URL looks like a base string plus a map that has been converted into a query string. I would write a script like the following to assemble it.

def base = 'https://chart.googleapis.com/chart?'

def params = [chs:'250x100', chd:'t:60,40', cht:'p3', chl:'Hello|World']

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

Nice and simple. The collect method applies the closure to the params map, transforming each entry from a key, value pair into the string “key=value” and returns the resulting list. Then the join method produces a string by connecting each of the list elements with the ampersand delimiter. I’ve been telling people that this particular combination of collect method, closure, and join is a very useful way to assemble a query string from a map of parameters.

Yesterday, however, I was showing the students that according to the Groovy JDK there are two versions of the each iterator on java.util.Map. One version takes a two argument closure that automatically separates the keys from the values, just as I did above. The other uses a single argument closure, which treats each element as an instance of Map.Entry, so that you have to call it.key or it.value (i.e., it.getKey() and it.getValue()) to get the keys and values individually.

To illustrate the point, I took a trivial map and printed out the keys and values, and then I printed out the map entries, at which point I got a surprise.

[x:1, y:2, z:3].each { k,v -> println "$k=$v" }
[x:1, y:2, z:3].each { println it }

Lo and behold, the map entries printed out in the form “key=value”. In other words, the toString method on Map.Entry prints exactly what I needed for the query string.

It then occurred to me to look and see if all the other methods on Map (like find, findAll, count, sort, and especially collect) also had both one- and two-argument closure versions, just like each. And, sure enough, they all did.

In other words, instead of

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

all I really need to write is
def url = base + params.collect { it }.join('&')

and I get the same result. The collect method transforms the map into a list whose elements are the map entries, and then the join method invokes toString on each and assembles the query string out of the result.

Wow. As simple as my original code was, I’ve been doing it the hard way all along.

Of course the down side is that now I need to go back and revise all my similar examples in my book, Making Java Groovy, available in Early Access Form from Manning at http://manning.com/kousen (new Testing chapter added this week).

That’s a small price to pay for discovering that Groovy is even simpler than I realized. :)


Kenneth Kousen

About Kenneth Kousen

Ken Kousen is a Java Champion, several time JavaOne Rock Star, and a Grails Rock Star. He is the author of the Pragmatic Library books “Mockito Made Clear” and “Help Your Boss Help You,” the O'Reilly books “Kotlin Cookbook”, “Modern Java Recipes”, and “Gradle Recipes for Android”, and the Manning book “Making Java Groovy”. He also has recorded over a dozen video courses for the O'Reilly Learning Platform, covering topics related to Android, Spring, Java, Groovy, Grails, and Gradle.

His academic background include BS degrees in Mechanical Engineering and Mathematics from M.I.T., an MA and Ph.D. in Aerospace Engineering from Princeton, and an MS in Computer Science from R.P.I. He is currently President of Kousen IT, Inc., based in Connecticut.

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »