Enterprise Java

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.

The sample code used in this post can be found here.

REST IN SHORT
REST (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:

@Path("/people/{code}")
 public class Individual {

     @GET
     @Produces({"application/json", "application/xml"})
     public Object find(@PathParam("code") String code) { ... }

     @DELETE
  public void remove(@PathParam("code") String code) { ... }
 }

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:

@Component
 @Scope("request")
 @Path("/people/{code}")
 public class Individual {
     ...
 }

Finally, just tell Spring where to look for your components:

<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">

     <context:component-scan base-package="your.namespace.here" />
 </beans>

the – surprise – Inject annotation to populate their fields. That’s all… you’ve got a REST resource ready to go.

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.

Reference: RESTful Web Applications with Jersey and Spring from our JCG partner Karl Agius at the The Simple Part blog.

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
sherkhanabc
sherkhanabc
9 years ago

Here is an example on Spring 3, Jersey 2.6, REST API, Grizzly 2.3.11

http://www.webtuts.in/spring-3-rest-using-jersey-2-6-and-grizzly-integration-example/

Back to top button