About Karl Agius

RESTful Web Applications with Jersey and Spring

A couple of months ago, we were tasked with creating an API to expose some functions in our system to third party developers. We chose to expose these functions as a series of REST web services. I got to play with Jersey, the reference implementation of JSR 311 (Java API for Restful Services); this turned out to be a nice surprise, as it proved to be extremely powerful and elegant. In this post, we’ll create a very simple REST web service using Jersey.

REST IN SHORTREST (Representation State Transfer) is not new – it was first proposed in 2000 (Fielding, Architectural Styles and the Design of Network-based Software Architectures) – but it’s still quite underused today, having only really come into fashion these last couple of years. It is used to describe resources through a URL, and allows the manipulation of such resources. The idea is to leverage the HTTP Protocol to create a platform-agnostic, stateless, cache-friendly interface between client and server. While REST can be applied to other protocols, we are only concerned with HTTP at this time.

In simpler terms, a URL like “http://www.myserver.com/files/text.txt” describes a resource which is a file called text.txt, and lives in the myserver.com domain. Nothing fancy there; you can point your browser to that file, and your browser will send a GET request to the server to fetch it. You don’t even need to write any application to do that; any client and server will communicate in that manner.

It gets more interesting with the other request methods; everyone reading this should be familiar with the POST method (typically used for forms). In a REST application, POSTing to a URL means you want to edit the resource at that URL. The less common PUT and DELETE methods are used to create and delete resources, respectively; for example, PUT http://www.myserver.com/files/text.txt should create a text file, usually with the contents of the body of the request. It is worth noting that in some systems, particularly ones which are meant to interact directly with a browser, the POST method is sometimes hijacked for these purposes, since some browsers don’t deal with these two very well.

REST also makes use of headers, to control caching, or to determine which content types or languages the client is expecting; a request is, after all, a plain old HTTP request. It’s nice, it’s clean, it’s flexible, and it won’t do your head in with the amount of plumbing you’d need to provide the same functionality with, say, SOAP. The reason we went with it should be clear enough at this point.

ANATOMY OF A REST RESOURCE CLASS While there’s plenty going on behind the scenes, Jersey does a very good job of hiding the complexity behind its nice clean annotations. Consider the following:

This is a simple class which can look up or remove the entry for a person, based on a unique code. The first annotation, Path, specifies which URL this class (or method – you can override the path at method level, should you wish to do so) maps to. In this case, we’re saying that we want this class to handle requests made to “[whatever domain]/people”; we will also be expecting a value after “people”, which we shall consider to be the unique code for the person we want – that’s the value in braces, there.

We can use multiple variables in the path; we could, for example, say “/team/{team_id}/{position}” or even “/team/{team_id}/staff/{position}” to get the details of the persons filling a given position in a team, depending on how verbose we want to be. We can also create impose restrictions on the parameters; if we wanted code to be a numeric value, for example, we can define it as “{code: [0-9]*}”; the definition accepts regular expression patterns.

The GET and DELETE annotations specify which Java method should handle which HTTP method. There are also POST and PUT annotations for those methods.

The PathParam annotation grabs parameters from the request URL and passes them on to the method – in this case, it grabs the code parameter. Self explanatory so far – there are even FormParam and HeaderParam versions to grab values from POSTed form fields or request headers, respectively.

I found the Produces annotation quite interesting. The parameter to the annotation takes a collection of MIME types, which declare the return types which the method is capable of generating. In both cases above, we can serve JSON or XML responses – the one that gets returned is picked based on the value of the request’s ACCEPT header – if the request accepts more than one of the return types provided by the method, the first one to be listed in the ACCEPT header is preferred.

Returning whatever When returning an instance of a class which is annotated with XmlRootElement, Jersey takes care of determining the return type, and converting the object into the required representation. No fuss, no muss needed. If you need to do some fancier formatting – converting to a PDF or an html page, for example, it should be as simple as writing and registering a marshaller for the given type, though I haven’t delved this deep yet.

WIRING IT ALL UP WITH SPRING Of course, that resource class is just sitting pretty right now. To put it up in a web application, we’ll need to set it up, and Spring is what we’ll use for this. Bear with me; it’s not very verbose, for once.

First, we need to tell Spring that our resource is a configurable component. To do this, we can just plonk the Component annotation on the class. Then, we need to define the scope; since REST is meant to be stateless, we’ll just go ahead and declare a request scope, using the Scope annotation with a value of “request”. No surprises yet! Our class declaration now looks like this:

IT’S NOT ALL WALKING That’s really all there is to it. Apart from a few problems I’m still looking into – JAXB totally loses its marbles when it finds a circular reference, making some object models difficult to marshal – JSR 311 provides a really clean way to put this all together.

There’s one gripe; collection return types seem to be a problem. This can be bypassed by wrapping collections in a container, but it does seem like an unnecessary step.

THE SAMPLE APPLICATION The sample application can list, load or delete individual entries from an in-memory map on the server via jQuery ajax calls. It has been packaged in two WAR files (server and client). Due to browser sandboxing, make sure that both client and server packages are on the same domain; this restriction does not exist if you connect to the server programmatically.

I suppose I could have shown an example of POST or PUT, but really, it’s straightforward enough and I really hate writing forms.

Career Opportunities

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Receive Java & Developer job alerts in your Area from our partners over at ZipRecruiter

Leave this field empty if you're human:

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.