In this blog post a small usage example of Jackson (http://jackson.codehaus.org), a very useful high-performance JSON processor written in java.
At the end of this post you will be able to perform an http call to the Google Geocoding API (http://code.google.com/apis/maps/documentation/geocoding) providing an address as a parameter, parse the result with Jackson and retrieve the coordinates of that point. Personally I was surprised how simple Jackson can be.
Jackson provide three alternative methods to get what you want
- Streaming API: reads and writes JSON content as discrete events.
- Tree Model: provides a mutable in-memory tree representation of a JSON document.
- Data Binding: converts JSON to and from POJOs based either on property accessor conventions or annotations.
In my situation I simply needed to parse the JSON response and retrieve the two values for the coordinates. These values are in fixed positions in the JSON. In the beginning I was tempted to go for a Data Binding approach, but at a second glance the needed to create a java object mapping all the json structure did not result very attractive. Needing to retrieve only to values from the whole JSON the Tree Model approach is the one which suits the best. You will see here below how quick it is.
First of all, here below the two dependencies you should put in the pom of your project. Please note that the jackson libraries are very light and have zero dependencies, they rely only on the JDK. Check the Jackson website which is the last version released; in the moment when this blog post was written it was the 1.7.4. The Jackson dependencies are provided with two possible licenses: LGPL and ASL. Choose the one that better suits your project.
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.7.4</version>
</dependency>
At this point have a look to an example of google geocode service response at http://code.google.com/apis/maps/documentation/geocoding/#GeocodingResponses. The fields we will retrieve are ‘lat’ and ‘lng’ and they are in the subnode ROOT -> results -> address_components -> geometry -> location.
The code here below will perform an http request to the google geocode service, will feed the resulting InputStreamReader to the Jackson ObjectMapper and will browse the nodes till the one we are interested in. The great thing is we do not need to go through every single node till we reach the node we are interested in. We can simply perform a call rootNode.findValue(“location”) and this will look up the node in the descendents of the root, not only in children. This will free us to specify the complete path and will make our code very flexible. The format of JSON we are computing can change, but our code will keep on working till the location node will be a descendent of the root, no matter where it will be placed exactly.
URL googleMapsUrl = new URL("http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=" + URLEncoder.encode(address, "UTF-8"));
URLConnection connection = googleMapsUrl.openConnection();
InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream(), "UTF-8");
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readValue(getGoogleInputStream(address), JsonNode.class);
JsonNode locationNode = rootNode.findValue("location");
String latitude = locationNode.findValue("lat").toString();
String longitude = locationNode.findValue("lng").toString();
Please note this is not at all production ready code, it is simply a set of instructions relevant for the example I collected from here and there from different methods, only to give you an idea about the actions to be performed. Make sure all possible exceptions are catched and refactor the code more conveniently in different methods.
A final note: if you are planning to use the Google Geocoding API please note that there are some usage limits. From the google website you can read that the use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day. If you wish to have more requests at your disposal you will have to upgrade to Google Maps API Premier.
0 Responses to “A simple Jackson example in tree model mode with maven: google geocode service parsing”