Creating RESTful webservices with the Spring Framework

With the Spring Framework you can easily create RESTful webservices. This is built-in the MVC part of Spring. In this post I show you how to configure this and offer the consumer the response as XML and as JSON.

The domain model

First we need a domainmodel. In this sample it is quite simple. It consists of 2 classes: Constellation and ConstellationName.

Domainmodel

The Constellation describes an astronomical constellation like Orion, Andromeda and so on. The association to ConstellationName offers names of the constellation in different languages.

The service model

In this sample the interface used by clients (web, webservice) is a classical service class. This class – named ConstellationService – needs a repository class to access the underlying database.

Servicemodel

Wiring domain and service

With Spring this is quite easy. You need only a little XML file and some Annotations. In the ConstellationService you add the @Service annotation:

This annotation is out of the package org.springframework.stereotype.Service. To inject the repository class you can use the @Inject annotation. If you have setup your JPA environment properly you can access the database and get some Constellation instances.

Creating the REST service

Now we have a working backend. But we want to have a RESTful webservice so we need another artifact in our sourcecode: the Controller. A controller is the first item of our application. This means if a client requests data the controller gets the request foremost. The controller then is analyzing and validating the request. After this service will be called, the retrieving data prepared and returned.

In Spring you can add some annotations to a controller method to map this method to the specified URL resource:

With this mapping this controller method responses to the request http://some-host/constellations only. You can map more complex URL resources too. For instance if you have an URL with parameter. In our service we want to offer a method the client can request for one constellation identified by its code. This can be done with the annotation @RequestMapping and @PathVariable:

With this mapping the part with the {} will be taken as parameter for the method. You can use more placeholder too. For this you can read the Spring documentation.

Now we have all informations to create the controller class.

The last step we need to do is to configure the Spring container to get it together. For this we need a little bit XML. In this XML we configure 2 views: one for a XML and one for a JSON response. So you need to add the xml or json extension to the url to control the format of the response.

First we configure the XMLMarshaller to generate XML out of the Java beans. Then we need 2 Views. One for XML and one for JSON. The most configuration needs the ContentNegotiatingViewResolver. This resolver handles the different response formats. The last property ignoreAcceptHeader you need to get JSON in your browser too. Otherwise always XML will be returned.

Configuring the web.xml

You need to activate the Spring servlet and the context listener to get the service running. This is done with a small web.xml.

Now we have all together and can start the web application. You can access the services with http://localhost:8080/rpc/constellations. As default format XML will be returned. If you want to have JSON change the URL into http://localhost:8080/rpc/constellations.json. Of course you can add .xml to get XML output, too.

If you want to have the data for one constellation you can use the 2nd controller method with http://localhost:8080/rpc/constellation_by_code/and. The last part of the URL is the official code/abbreviation of a constellation. All codes/abbreviations you can get here. If you want the output as JSON you can add the extension .json too: http://localhost:8080/rpc/constellation_by_code/and.json

Optimize the output

We have even 2 little problems:

  1. The Constellation class defines a byte array containing imagedata of a starcard. If we want to retrieve all constellations the response will be great.
  2. The association will not be resolved. We want to get all names of a constellation with one request to minimize the response-request cycle.
For the marshalling between XML and JAVA code we use XStream. With this library you can (de-)serialize XML from Java and vice versa. With XStream you can add an annotation to a class property to avoid the serialization. This annotation is named XStreamOmmitField.

public class Constellation{
  ...
  @XStreamOmmitField
  private byte[] starCardData;
}

The 2nd problem can be solved with the @XStreamImplicit annotation. The collection will be resolved and ebedded in the return data. Additionally you can set the name of the parent element of the collection in the XML data.

The XML result should look like

Conclusion

Now you have a Spring-based RESTful service created. As you can see there are not many code you must write. The most is configuration with annotation and some XML. With the @RequestMapping you can create powerful mappings from URL resources to controller methods. Another nice feature is to deliver the response as XML and JSON.

Resources

You will find all the code snippets at https://gist.github.com/1289371

Comments are closed.