RESTful HTTP with JAX-RS
In this post, we’ll look into creating a RESTful HTTP interface using JAX-RS. We’ll see that it is pretty easy to expose ordinary java methods through HTTP.
We’ll create a trivial model of a movie database and expose it via RESTful HTTP services as JSON and XML using JAX-RS, a little JAXB, Apache CXF, maven and Spring. We’ll see that we need very little code to achieve that. This post focuses on the service front-end, the data is not persisted. We’ll add JPA based persistence in a later post.
Contents
Preparation
To follow along, you’ll need a JDK 1.6, Â Eclipse Helios JEE and Maven. M2eclipse won’t hurt. To get started, grab the POM file from https://github.com/wwerner/JAXRSTutorial/raw/master/pom.xml.The complete source code is available on github. There is one branch for each step so you can easily switch back and forth and compare your state with the expected one.
The POM defines a number of dependencies. The most notable ones are CXF 1, Jackson 2 and Spring 3.
Run the following commands on the shell.
This will create the eclipse project we’ll be working on. I put in a little hack using the antrun plugin to create the source folders that would have been there if we started from an archetype. I’m pretty sure there is a better way to do this, please leave a pointer if you know.
CXF comes with quite a load of dependencies of it’s own, so you might want to get a coffee4 while maven downloads the internets.
After mvn finished, you should have the same file structure as in this branch: https://github.com/wwerner/JAXRSTutorial/tree/stage2
Import the created project into your workspace using Import->Existing Projects. The project should look like this in the project explorer view:
The Model
For our movie database, we’ll only have two model classes: Actor and Movie. A movie consists of a title and the cast which maps the movie’s roles to Actors. The poor Actor can only afford one property: his name.We’ll put all of this in a new package in our project: net.wolfgangwerner.tutorial.jaxrs.model in src/main/java.
See https://github.com/wwerner/JAXRSTutorial/tree/stage3.First Service
Now, what do we do to expose our model using HTTP? Let’s start with a trivial ‘Hello World’ service to outline the concepts. Â We start with a new package called net.wolfgangwerner.tutorial.jaxrs.service and add a class called MovieService.Now, the only thing we have to do to expose this method is to add some JAX-RS annotations, @GET, which tells the runtime that this method should be called on GET requests and @Path which defines the URI (template) for which this method should be called. Additionally, we’ll add @Produces to make explicit which content type we are returning.
See https://github.com/wwerner/JAXRSTutorial/tree/stage4.Wiring it up
We could now configure the JAX-RS servlet5 and deploy it into a servlet container. In this case, we also need to make sure that we have a JAX-RS implementation in the classpath.Anyway, I’d like to do it a little different6: We’ll use Spring IoC with the JAX-RS configuration namespace provided by CXF to define an HTTP server and publish our resource.
Create the file application-context.xml for Spring in src/main/resources and put in the following content.
Now what’s in there? First interesting thing is the declaration of the jaxrs namespace from CXF: xmlns:jaxrs=”http://cxf.apache.org/jaxrs. Then we define two beans, one for our service class and one for the jackson provider that will be used to render JSON representations.
The next part configures an HTTP server (CXF comes with jetty7) to run on localhost port 9001. We tell the runtime to look for services in the service bean we defined earlier and we register the jackson JSON provider with this server.
See https://github.com/wwerner/JAXRSTutorial/tree/stage5.Application
Next thing is to have an application we can start. For this tutorial, we do not run inside a web container but standalone. We’ll configure a server later on via spring, for now we just need something to start our application context.The application does nothing more than to look for a spring xml configuration file on the classpath and to start the configured context.
See https://github.com/wwerner/JAXRSTutorial/tree/stage6.Take it for a test drive
Your workspace should now look like this:
Select the Application class and choose Run as.. -> Java Application8
The console output should tell you that spring wired the dependencies, jetty started and is listensing on port 9001 as you told it to in the application context.

If  you followed my earlier tutorials, you’ll know Poster9, a firefox addon to make HTTP requests. If you don’t have it, get it or  use the HTTP speaking tool of your choice instead 10.
Use Poster to GET http://localhost:9001/hello . Remember we defined the server port in application-context.xml and path via the @Path annotation in MovieService.

Let’s try another thing: We can ask our service which kinds of interaction it supports using the OPTIONS HTTP verb11.
This tells us that we can execute GET, HEAD and OPTIONS requests on our /hello URL:

This is what it would look like with cURL:
R
That was pretty easy. Boring, too. Let’s see how we can map actual object hierarchies to different formats and write data back to our application.Some data
Before we add some more interesting services, let’s create some test data we can retrieve first. We’ll simply do so in the constructor of our service. In a later post, we’ll factor out a data store component that uses JPA for persistance. Stay tuned.]First we create a couple of actors, then we associate them with the movie using the cast map.
https://github.com/wwerner/JAXRSTutorial/tree/stage7More Services
Lets create a service that returns a movie by it’s id and can provide the result in JSON and XML format. The good message is that we don’t have to worry about marshalling and unmarshalling of our business objects. We can simply return Movie from our service method. Let’s give it a try and see what happens. Add the following method to our service class and call it using Poster/cURL/whatever.Note that we added an URL parameter {id} to the @Path annotation. We also added the @PathParam annotation to the id parameter in our method12.
That’s the result13:
We got JSON, as this is the first type defined in our @Produces annotation and the client did not send any preferences. Let’s add a request header that says ‘I’d rather take XML’14.

This returns … … … an error? Correct. A kind of cryptic one as well:
No message body writer has been found for response class Movie.
This means that the jax-rs runtime did not find anything to serialize our Movie. Jackson, the JSON processor is kinda smart, it just uses reflection to render JSON. But for XML, we need to Do Stuff™. How do we get that body writer? We don’t need to. We can just use JAXB annotations in our model to link our data to an XML representation. The first thing to do is to add the @XmlRootElement annotation on both our model classes.
If you run this, you might note that the cast may be displayed before the title. That’s fugly. Add@XmlType(propOrder={“title”, “cast”}) Â to the movie class, restart the application and you are good. The nice thing about the JAXB bindings is that they are also evaluated by jackson. Add the annotation @XmlElement(name=”who”) to the getName() method of Actor and see what happens.
Note that the “name” element changed in both representations.
Now you might argue that the default representations are still fugly. JAXB provides a nice mechanism to produce arbitrary output: @XmlAdapter. The approach is basically that you create a java class that produces the required XML output and an adapter that converts your business objects to the representation objects and vice versa. This seems overkill at first, but it is incredibly powerful. @bdoughan wrote a nice post on this if you want to dig deeper.Reading is always easy…
… writing back is more interesting. Well, not in this case. It’s exactly the same. Just swap the @GET for a @POST and @Produces for @Consumes, pass the Movie as parameter, add some logic to save the value and you are done. Ok, we’re not really persisting stuff, so just storing in memory may not count. We’ll address persistence via JPA in a later post.To see which data we have stored on the server, we’ll also add a new service that returns all movies. Note that (typed) collections are handled transparently as well.
To make it a little more interesting, we return a useful response that tells us which resource has been created15.
Just copy either the JSON or XML representation and POST it to the /movies URL using a new id. This will create a new movie and return it’s URL. You can also GET /movies to see a complete list of movies available.


I rest my case
We saw that it is pretty easy to expose simple java methods through HTTP.Two weeks before writing this post I gave a talk at the company I work with16 about REST and common REST misconceptions that also featured a live hacking session with the stuff you just read. Then I thought that I could reuse it for a blog. Then I went to Eclipse Summit Europe17 where @doug_clarke used JAX-RS in his talk, then @vogella published a tutorial on JAX-RS as well18.
I like to believe that it is an interesting topic more than I like to believe it is grossly redundant. Feel free to disagree, here’s my take on it anyway. As a side note, it’s actually only 89 lines of java code. That is pretty lean, I’d say. You can get each and every of these lines here. Awesome, isn’t it?
Also note that as we speak, a new version of the JAX-RS/JSR311 specification is proposed here.
I’ll follow up on this post with adding JPA persistence to our movie store. Stay tuned if you are interested.
As bedtime candy, here are some of the slides19 I used in my talk.
Btw., we are looking for java developers. Please feel free to contact me if you are interested.
- Â http://cxf.apache.org/ ↩
- Â http://jackson.codehaus.org/ ↩
- Â http://www.springsource.org/ ↩
- Or beer, depending on the time of the day ↩
- Â http://stackoverflow.com/questions/2072295/how-to-deploy-a-jax-rs-application ↩
- I like different approaches. And when I play, I try to be as independent of a certain stack as possible. I want to learn which part does what instead of relying on application server magic. ↩
- Of course. Nearly everything comes with jetty. ↩
- Alt-Shift-X, J if you are lazy, which you should be: http://threevirtues.com/ ↩
- https://addons.mozilla.org/de/firefox/addon/2691/ ↩
- In particular, I like cURL. curl -v -X <HTTP Verb> <URL> is your friend ↩
- Â http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html ↩
- Which I find particularly ugly. But it needs to be done. ↩
- After reformatting ↩
- For details see e.g. http://en.wikipedia.org/wiki/Content_negotiation ↩
- For details see https://cwiki.apache.org/WINK/jax-rs-request-and-response-entities.html, e.g. ↩
- http://bridging-it.de/ ↩
- http://www.eclipsecon.org/summiteurope2010/ ↩
- This guy is fast: It’s the third time he published something I was working on that point in time. ↩
- Image credit: http://rosewine.deviantart.com/#/d2sw85k, http://www.etsy.com/listing/33909593/fight-club-vegan-soap-unofficial-parody, http://www.flickr.com/photos/onesec/4464260372/, http://www.conti-online.com/generator/www/de/de/contisoccerworld/themes/02_fanzone/04_stars/20_world_cup_stars/1990-matthaeus-de.html ↩









This blog post was very helpful for me. Thanks!
Justin
26 Jan 12 at 19:39
I am very thankful that you took time to create this tutorial. It was of much help. Nice work!
Paulino
1 Nov 12 at 14:29
Hi there,
Did you manage to add the persistent layer to the movie store?
Sachin
17 Nov 12 at 13:23
That lines save me!!! THANKS from venezuela!!!
Error: No message body writer has been found for response class List….
and these lines solved de problem… repeat, THANKS!!
Elvisteck
2 Jan 13 at 06:09
Thank you so much. I spent 2 days to get my REST service to work with JSON… thanks to you i solved this problem easily. Greetz, Christian.
Christian
14 Apr 13 at 18:17