Home > Articles > Programming > Java

Java Reference Guide

Hosted by

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Consuming RESTful Web Services using Spring's RestTemplate

Last updated Mar 14, 2003.

If youโ€™re looking for more up-to-date information on this topic, please visit our Java article, podcast, and store pages.

One of the main benefits in using RESTful Web Services, other than having a RESTful architecture, is that you no longer have to work with complicated SOAP XML files. In the previous section we further simplified things by using the XStream XML serialization library to convert regular Plain Old Java Objects (POJOs) into our XML responses. The question that now presents itself is: how do we properly consume RESTful web services?

When using Spring, the answer is very straightforward: use the RestTemplate. Spring provides a host of different template classes that abstract many of the details in working with different technologies, for example it has a JdbcTemplate class for making database queries, a HibernateTemplate class for interacting with a data model using Hibernate, and a JmsTemplate for sending and consuming JMS messages. Likewise, Spring has developed a RestTemplate to help you better consume RESTful web services.

Using the RestTemplate is fairly simple:

  1. Create an instance of the RestTemplate class
  2. Configure a message converter that translates REST messages to objects
  3. Invoke one of its methods that performs the requested operation and returns the requested response

And, as we'll see in the example at the end of this section, you can do it all using an application context configuration file and Spring's annotations, even when running as a client application outside the context of an enterprise application. The important thing is to understand how the RestTemplate works and how you can configure XML-to-object conversion.

The RestTemplate has built-in support for the following HTML message converters:

  • StringHttpMessageConverter: can read and write strings from the HTTP request and response; supports all text media types (text/*)
  • FormHttpMessageConverter: can read and write form data from the HTTP request and response; uses the type application/x-www-form-urlencoded; form data is of the form MultiValueMap<String,String>
  • ByteArrayHttpMessageConverter: can read and write byte arrays from the HTTP request and response; supports all media types (*/*) with a content type of application/octet-stream
  • MarshallingHttpMessageConverter: can read and write XML from the HTTP request and response using Spring's Marshaller and Unmarshaller interfaces found in the org.springframework.oxm package
  • MappingJacksonHttpMessageConverter: can read and write JSON from the HTTP request and response using Jackson's ObjectMapper
  • SourceHttpMessageConverter: can read and write javax.xml.transform.Source from the HTTP request and response; supports DOMSource, SAXSource, and StreamSource
  • BufferedImageHttpMessageConverter: can read and write java.awt.image.BufferedImage from the HTTP request and response

As you now understand, the RestTemplate class is far more powerful than simply passing data back and forth between a web service server and client. It has the ability to transform the data being sent or received into any number of forms. In this example we're going to explore the MarshallingHttpMessageConverter and learn how to plug in different XML marshaling implementations.

There are different ways that you can configure a RestTemplate, which include manually creating one and configuring it in your application code or defining an applicationContext.xml file and letting Spring wire it together for you. In this example I opted for the latter to create a client that can consume messages produced by the ArticleService web service created in the previous section.

Listing 1 shows the contents of the applicationContext.xml file.

Listing 1. applicationContext.xml

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:oxm="http://www.springframework.org/schema/oxm"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/
   schema/beans/spring-beans-2.5.xsd 
			http://www.springframework.org/schema/context http://www.springframework.org/
           schema/context/spring-context-2.5.xsd 
			http://www.springframework.org/schema/oxm http://www.springframework.org/
           schema/oxm/spring-oxm-3.0.xsd">

	<context:component-scan base-package="com.informit.articleservice" />

	<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
		<property name="messageConverters">
			<list>
				<!-- We only have one message converter for the RestTemplate, namely the XStream Marshller -->
				<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
					<constructor-arg>
						<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
							<!-- Explicitly define the aliases -->
							<!--
							<property name="aliases">
								<props>
									<prop key="article">com.informit.articleservice.model.Article</prop>
									<prop key="category">com.informit.articleservice.model.Category</prop>
								</props>
							</property>
							-->
							
							<!-- Tell XStream to find the alias names in the following classes -->
							<property name="annotatedClasses">
								<list>
									<value>com.informit.articleservice.model.Article</value>							
									<value>com.informit.articleservice.model.Category</value>							
								</list>						
							</property>
						</bean>
					</constructor-arg>
				</bean>
			</list>
		</property>
	</bean>
</beans>

The applicationContext.xml file defines one bean, namely the restTemplate bean, which is implemented by the org.springframework.web.client.RestTemplate class. The RestTemplate class provides a setter method to define message converters. Into this property we inject a list that contains a single bean: a MarshallingHttpMessageConverter. This is your entry point to define any of the aforementioned converters, but in this case we want to convert the response to an object.

The process of converting an object to XML is referred to as marshallling and the process of converting the XML back to an object is referred to as unmarshalling and Spring provides support for several open source projects:

  • Jaxb2Marsheller: used to convert objects to and from XML in the JAXB 2.0 format
  • CastorMarshaller: used to convert objects to and from XML files using the open source Castor XML binding framework
  • XmlBeansMarshaller: XMLBeans is an Apache project that provides XML Schema support; this marshaller uses the XMLBeans library for converting objects to and from XML
  • JibxMarshaller: JiBX is a framework through which you define rules for how your objects and converted to XML documents; this marshaller performs the conversion using JiBX
  • XStreamMarshaller: XStream is a simple XML serialization library, which we used in the simple example created in the previous section. It does not have strong support for XML namespaces, so it is not suitable for consuming complicated RESTful service responses, but it is simple and it illustrates how to consume our ArticleService messages

The MarshallingHttpMessageConverter takes, as a constructor argument, a reference to an XML marshaller. You can use any of the aforementioned marshallers, and in listing 1 I created an XstreamMarhaller instance. XStream can be configured to map aliases to beans or the beans can be annotated themselves. In the previous section we annotated the model beans with the @XStreamAlias alias that defines the alias for each bean. When converting an object to an XML document XStream can discover the annotation, but when converting an XML document to an object it cannot. Therefore you have two options: define the aliases in the aliases property of the XStreamMarshaller class or set an array of annotated class names in its annotatedClasses property. I opted for the latter, but I showed the former for your reference.

With the restTemplate bean defined, listing 2 shows the ArticleClient, which uses the restTemplate to communicate with the ArticleService.

Listing 2. ArticleClient.java

package com.informit.articleservice.client;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.informit.articleservice.model.Article;
import com.informit.articleservice.model.Category;

/**
 * Client used for communicating with the ArticleService RESTful web service
 * @author shaines
 *
 */
@Component( "articleClient" )
public class ArticleClient
{
	/**
	 * Facilitates communication with the ArticleService; autowired by Spring
	 */
	@Autowired
	protected RestTemplate restTemplate;

	/**
	 * The base URL of the ArticleService web service - should be configurable
	 */
	private final static String articleServiceUrl = "http://localhost:8080/articleservice/";
	
	/**
	 * Returns the categories defined in the ArticleService
	 * 
	 * @return			A List of categories defined in the ArticleService
	 */
	@SuppressWarnings( "unchecked" )
	public List<Category> getCategories()
	{
		return restTemplate.getForObject( articleServiceUrl + "article", List.class );
	}
	
	/**
	 * Returns the requested article from the ArticleService
	 * 
	 * @param category	The category of the article to return
	 * @param id		The id of the article to return
	 * 
	 * @return			The request article
	 */
	public Article getArticle( String category, int id )
	{
		return restTemplate.getForObject( articleServiceUrl + "article/{category}/{id}",
       Article.class, category, id );
	}
	
}

The ArticleClient is configured to have the RestTemplate auto-wired into it, which it will be as long as the ArticleClient is loaded by a Spring application context. You'll notice that the ArticleClient is configured with the @Component annotation and that the applicationContext.xml is configured to scan the com.informit.articleservice package (and its sub-packages) for Spring classes. Therefore, when the ArticleClient is loaded from the application context, it will be automatically populated with a reference to the configured RestTemplate instance.

The RestTemplate class defines several methods that are of the form:

commandForReturnValue

Where the command is defined for the HTTP commands, such as get, post, put, delete, head, and options, and the return value is the information that you want to retrieve from the service. The examples that the JavaDoc provides are as follows:

  • delete(): deletes an object hosted by the web service
  • getForObject(): executes the HTTP GET command and returns the requested object
  • headForHeaders(): executes the HTTP HEAD command and returns the headers for the requested service
  • optionsForAllow(): executes the HTTP OPTIONS command and returns list of content types the the request service allows
  • postForLocation: executes the HTTP POST command and returns the location header value
  • postForObject(): executes the HTTP POST command and returns the object at the specified URL
  • put(): executes the HTTP PUT command and sends the specified object to the web service
  • execute(): provides fine grained control if one of the aforementioned methods does not suit your needs

In this case we are executing a GET and retrieving the corresponding object. The getForObject() method accepts as parameters:

  1. The URL of the service to communicate with
  2. The class of the object to be returned
  3. An optional set of bind parameters for the URL, if they are present, such as in our getArticles() method. The URL has two bind parameters, namely category and id, so we pass in two values: the category string to bind and the id integer to bind

The next step is to obtain a reference to the ArticleClient and use it. Listing 3 shows the contents of the RestTemplateExample class that does just that.

Listing 3. RestTemplateExample.java

package com.informit.resttemplateexample;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.informit.articleservice.client.ArticleClient;
import com.informit.articleservice.model.Article;
import com.informit.articleservice.model.Category;

public class RestTemplateExample
{
	public static void main( String[] args )
	{
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(	"applicationContext.xml" );
		ArticleClient articleClient = applicationContext.getBean( "articleClient", ArticleClient.class );
		
		Article article = articleClient.getArticle( "fun", 1 );
		System.out.println( "Article: " + article );
		
		List<Category> categories = articleClient.getCategories();
		for( Category category : categories )
		{
			System.out.println( "Category: " + category );
		}

	}
}

The RestTemplateExample class loads the applicationContext.xml file from the CLASSPATH, retrieves the “articleClient” bean, which is named by the @Component annotation on the bean and identified by Springs component scan, and then invokes its two methods to demonstrate how it works. Be sure to deploy the article service web service developed in the previous section to your web container and start it before executing this class (and change the URL if you need to.)

When I run this example I get the following output (including a bunch of logging that I omitted):

Article: My Article by Steven Haines: A facinating article
Category: fun
Category: work

Finally, to pull of this together, listing 4 shows the Maven POM file for the project.

Listing 4. 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.informit</groupId>
	<artifactId>resttemplateexample</artifactId>
	<packaging>jar</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>resttemplateexample</name>
	<url>http://maven.apache.org</url>
	
	<properties>
		<spring.version>3.0.0.RELEASE</spring.version>
		<java.version>1.6</java.version>
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.0.2</version>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
						<manifest>
							<addClasspath>true</addClasspath>
							<classpathPrefix>lib/</classpathPrefix>
							<mainClass>com.informit.resttemplateexample.RestTemplateExample</mainClass>
						</manifest>
					</archive>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<executions>
					<execution>
						<id>copy</id>
						<phase>install</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory>${project.build.directory}/lib</outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
	
	<dependencies>
		<!-- Spring Dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.oxm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>1.3.1</version>
		</dependency>
		<dependency>
    		<groupId>commons-logging</groupId>
    		<artifactId>commons-logging</artifactId>
    		<version>1.1.1</version>
		</dependency>
		
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.6</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<!-- Add the Spring Maven Repositories to this project -->
	<repositories>
		<repository>
			<id>com.springsource.repository.bundles.release</id>
			<name>SpringSource Enterprise Bundle Repository - Release</name>
			<url>http://repository.springsource.com/maven/bundles/release</url>
		</repository>
	</repositories>

</project>

The POM file defines the location of the Spring 3 repository, includes the necessary Spring dependencies, and then configures the build to define a MANIFEST file that includes all dependencies and a main class to execute. After you build by executing mvn clean install, you can execute the application from the target directory as follows:

java -jar resttemplateexample-1.0-SNAPSHOT.jar

The RestTemplate class makes simple work out of consuming RESTful web services in Spring. This example showed how to consume a simple RESTful web service response using the XStream XML serialization library, specifically in the context of consuming messages produced by the article service, defined in the previous section.