Karl is a geek who loves to play with all sorts of frameworks and languages, and has a nice monitor tan to show for it. Karl is a DZone MVB and is not an employee of DZone and has posted 6 posts at DZone. You can read more from them at their website. View Full User Profile

RESTful Web Applications with Jersey and Spring

12.06.2010
| 31592 views |
  • submit to reddit

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:

   1: @Path("/people/{code}")
   2: public class Individual {
   3:
   4:     @GET
   5:     @Produces({"application/json", "application/xml"})
   6:     public Object find(@PathParam("code") String code) { ... }
   7:
   8:     @DELETE
   9:  public void remove(@PathParam("code") String code) { ... }
  10: }

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:

   1: @Component
   2: @Scope("request")
   3: @Path("/people/{code}")
   4: public class Individual {
   5:     ...
   6: }

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

   1: <?xml version="1.0" encoding="UTF-8"?>
   2: <beans xmlns="http://www.springframework.org/schema/beans"
   3:        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   4:        xmlns:context="http://www.springframework.org/schema/context"
   5:        xsi:schemaLocation="
   6:            http://www.springframework.org/schema/beans
   7:            http://www.springframework.org/schema/beans/spring-beans.xsd
   8:            http://www.springframework.org/schema/context
   9:            http://www.springframework.org/schema/context/spring-context.xsd">
  10:
  11:     <context:component-scan base-package="your.namespace.here" />
  12: </beans>

Where “your.namespace.here” is obviously the namespace for your resource classes. Should you need to inject any Spring beans into your components, you can use 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.

 

From http://karlagius.com/2010/12/05/restful-web-applications-with-jersey-and-spring/

Published at DZone with permission of Karl Agius, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Frederic Cuillandre replied on Mon, 2010/12/06 - 3:43pm

thanks for this article

we're using it since 6 months and it's a pleasure to work with... testing part of jersey is very simple.

the work done by the jersey team is grerat and the users mailing list is really useful.

F.

Rickard Oberg replied on Mon, 2010/12/06 - 9:59pm

The above shows one of the most common anti-patterns in "REST" development today: exposing the domain model. I've written a blog entry that outlines the issues with this, and what to do instead:

http://www.jroller.com/rickard/entry/the_domain_model_as_rest

Hope this helps!

Claude Lalyre replied on Wed, 2010/12/08 - 10:17am in response to: Rickard Oberg

This post is as valuable as gold ! Thanks for sharing your knowledge !

Snehal Masne replied on Tue, 2014/08/12 - 9:02am

If you're a Spring MVC user you're probably developing HTML web applications. REST concepts apply to web services and to web applications alike especially in rich client interactions. In addition to the features discussed in this article, Spring 3 also adds support for RESTful web applications. Here is a partial list: a new JSP custom tag for building URLs from URL templates, a servlet filter for simulating form submissions based on HTTP PUT and DELETE, a ContentTypeNegotiatingViewResolver for automating view selection based on content type, new view implementations, and more. Last but not least is the updated and much improved Spring documentation.


Regards,

Snehal Masne 


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.