Spring 3.0 has support for REST style WebServices, the Spring MVC controllers facilitate the functionality. In this example I will show an example of how to implement a basic REST service that uses XML marshalling to sent information over HTTP. Disclaimer: this is not an in depth tutorial for building REST style WebServices.
The Spring MVC controller
The Spring 3.0 REST support relies havily on Spring MVC. You need to use the Spring MVC Controller for implementing REST style WebServices with Spring. To declare a Controller you can use the Spring annotation based configuration. In this example I have annotated the ProductRestService class with the @Controller annotation. In order for Spring to pick-up the annotation Spring needs to be configured to scan for annotation (see the Spring configuration section).
REST uses templates that describe the URI to be used to invoke a WebService method. These URI templates can contain variable placeholders which allow for passing information to the WebService. The URI template contains all the information required for invoking a RESTfull GET method.
The @RequestMapping annotation allowes you to define the URI and HTTP method that are mapped to a method. In this example I have annotated the ProductRestService.getProductById(Long productId) with the @RequestMapping.
The value of the @RequestMapping, in this case: /products/{productId} , defines the URI that is mapped to this method. The productId variable needs to be defined when invoking the method and will be resolved automatically by Spring MVC with the value from the request URI. You can use the @PathVariable to inject the value of the productId variable directly into a method parameter.
The @ResponseBody annotation tells Spring to marshall the return value of the method to the HTTP response body. Spring allowes you to configure HTTP message converters that take care of conversion of the return value to a format which is accepted by the client. In this example the return value will be marshalled to XML using XStream.
package com.oudmaijer.spring.rest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* This is an example REST style MVC controller. It serves as an
* endpoint for retrieving Product Objects.
*/
@Controller
public class ProductRestService {
/**
* This method returns a specific Product. The URI to request a Product is
* specified in the @RequestMapping.
*
* @param productId the identifier of the requested product
* @return a Product
*/
@RequestMapping(value="/products/{productId}", method = RequestMethod.GET)
@ResponseBody
public Product getProductById(@PathVariable Long productId) {
Product p = new Product();
p.setId(productId);
return p;
}
}
Spring configuration
The configuration is where all the magic happens. It is important to define the <mvc:annotation-driven /> element at the end of the configuration file or else Spring will not register the marshallingHttpMessageConverter. It took me some time to figure this out ;(
You need to add the MessageConverters to the configuration in order to get the OXM marshalling to work. Spring uses the requests Accept header to determine which converter to use.
<?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" xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc" 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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!-- Enable annotation scanning. --> <context:component-scan base-package="com.oudmaijer.spring.rest" /> <!-- Define the OXM marshaller which is used to convert the Objects <-> XML. --> <bean id="oxmMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller" /> <bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <property name="marshaller" ref="oxmMarshaller" /> <property name="unmarshaller" ref="oxmMarshaller" /> </bean> <!-- Required for REST services in order to bind the return value to the ResponseBody. --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <util:list id="beanList"> <ref bean="marshallingHttpMessageConverter" /> </util:list> </property> </bean> <!-- Should be defined last! --> <mvc:annotation-driven /> </beans>
Maven2 dependencies
You need to add a couple of Maven2 dependencies to get the project up and running. Below is the entire pom.xml.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.oudmaijer.spring.rest</groupId>
<artifactId>spring-3.0-rest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- http://maven.apache.org/plugins/maven-compiler-plugin/ -->
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.0.RELEASE</version>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.0.RELEASE</version>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.0.0.RELEASE</version>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>3.0.0.RELEASE</version>
<optional>false</optional>
</dependency>
<dependency>
<groupId>xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.2.2</version>
<optional>false</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Web deployment descriptor: web.xml
Last but not least the web.xml. Since the REST support in Spring is based on Spring MVC you need to define the DispatcherServlet. Make sure to map the correct URL pattern to the DispatcherServlet.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>spring-3.0-rest</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/META-INF/spring/*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Invoking the service
This example only supports the HTTP GET method. If you want to test or build a client that uses REST WebServices you should use the RestTemplate in Spring. We can easily validate if the example WebService is running by accessing the service through Firefox. This will result in the following response.
For more information on REST support in Spring 3.0 please refer to the Spring reference documentation.

nice article!
I’ll add that in order to have well formed xml in the browser you may add aliases:
http://static.springsource.org/spring-ws/sites/1.5/reference/html/oxm.html
so you will have for example instead of
on the other hand, I’d like to know how do you proceed for unitary tests ? i use jersey but there may be another solution
[...] Spring 3.0: REST services with Spring MVC « oudmaijer.com | – Spring 3.0 has support for REST style WebServices, the Spring MVC controllers facilitate the functionality. In this example I will show an example of how to implement a basic REST service that uses XML marshalling to sent information over HTTP [...]
Social comments and analytics for this post…
This post was mentioned on Twitter by viskovic: http://www.oudmaijer.com/blog/2010/01/16/spring-3-0-rest-services-with-spring-mvc/…
You saved my day. Thanks.
How can I fine tune the url mapping in web.xml? How to configure it if I want the DispatcherServlet to serve only requests that come from “/products/*” pattern? In case of “/*” pattern everything goes through this servlet. If I put “/products/*” pattern in url-pattern in web.xml it keeps saying that no mapping is found for HTTP request.
That is because the URL`s in the Spring controller are relative to the Servlet mapping. So if you change the web.xml to /products/* you also need to change the mapping in the controler to /{productId}
If not the request is accessible through: /products/products/etc
how do i run this? what is the URL path?
Update the post with the correct image url. Click the image to see the URL.
http://url:port/context-root/products/1
Best regards, Stephan
Nice & useful article
Nice article, Question..?
If I want the method “getProductById” to return in the different format such as XML or JSON. For example:
I will call the method like below:
Returning in XML
http://localhost:8080/spring-3.0-rest/product/1.xml
Returning in JSON
http://localhost:8080/spring-3.0-rest/product/1.json
Could you please guide how to do in spring 3 and thanks for sharing.
Hi Tin,
suffixing the response return type is typically not the way to go with RESTful services. RESTful services typically return a specific format based on the Content Negotiation of the Client and the Server (http://en.wikipedia.org/wiki/Content_negotiation). You define what response type you expect by setting the HTTP Accept header to application/xml or application/json. Spring uses a ContentNegotiatingViewResolver for this.
Also have a look at this article: http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/
Summary
Basically, your service has 1 URL: http://localhost:8080/spring-3.0-rest/product/1 and based on the Accept header it returns either XML or JSON. You do not need 2 methods in your controller, just two Marshallers on for XML and one for JSON. This can be done based on JAXB annotations and Jackson.
If you still experience problems, let me know!
Thanks for your reply, That’s really helpful for me to learn more. I also got the answer from spring forum and both of you make me clear about how to make REST and RESTFul in spring 3.
Good basic article on spring rest services. Spring REST services
Hi Krishna,
the article you are refering to uses JAX-RS (Jersey) and not Spring MVC based RESTful services.
Can you please send me the War file without the jars?
I have setup it but getting error like below for my url
description The requested resource (/ProjTmplWar/ocn/1/oppoId/2) is not available.
Looks like old files that are still referenced in your workspace. Are you using Eclipse? Try cleaning the project.
Thank you, thank you, thank you. And thank you again. I spent the whole day today trying to get it to work, and I’ve no idea how much longer I would be banging my head on the wall if
I didn’t find your article.
Good to hear my article helped you getting started!
Regards, Stephan
Hi soudmaijer,
First of all thanks for your post. This post help me to learn Rest services with Spring 3.
I try to develop exactly the same example but when I deploy the example and navigate to: http://localhost:8080/restservice/products/1, I have a HTTP ERROR: 406, NOT_ACCEPTABLE.
Anyone can help me?
Thanks!
Hi Gerard,
406 has something to do with incorrect Accept of the Content Type. What browser are you using?
Cheers, Stephan
If you’re interested in generating documentation for a standard Spring 3 RESTful service, you should check out RESTdoclet (recently outsourced by IG Group). More info and links here: http://soaprobe.blogspot.co.uk/2012/07/rest-service-documentation-using.html
Robert
I am trying to return a PDF document that has been generated by the backend. I do not wish for any Spring Conversion to happen, what should my ContentNegotiatingViewResolver and MarshallingView look like?
-thank you.