The RestTemplate
is the core class for
client-side access to RESTful services. It is conceptually similar to
other template classes in Spring, such as
JdbcTemplate
and JmsTemplate
and other template classes found in other Spring portfolio projects.
RestTemplate
's behavior is customized by providing
callback methods and configuring the
HttpMessageConverter
used to marshal
objects into the HTTP request body and to unmarshall any response back
into an object. As it is common to use XML as a message format, Spring
provides a MarshallingHttpMessageConverter
that
uses the Object-to-XML framework that is part of the
org.springframework.oxm
package. This gives you a
wide range of choices of XML to Object mapping technologies to choose
from.
This section describes how to use the
RestTemplate
and its associated
HttpMessageConverters
.
Invoking RESTful services in Java is typically done using a helper
class such as Jakarta Commons HttpClient
. For
common REST operations this approach is too low level as shown
below.
String uri = "http://example.com/hotels/1/bookings"; PostMethod post = new PostMethod(uri); String request = // create booking request content post.setRequestEntity(new StringRequestEntity(request)); httpClient.executeMethod(post); if (HttpStatus.SC_CREATED == post.getStatusCode()) { Header location = post.getRequestHeader("Location"); if (location != null) { System.out.println("Created new booking at :" + location.getValue()); } }
RestTemplate provides higher level methods that correspond to each of the six main HTTP methods that make invoking many RESTful services a one-liner and enforce REST best practices.
Table 19.1. Overview of RestTemplate methods
The names of RestTemplate
methods follow a
naming convention, the first part indicates what HTTP method is being
invoked and the second part indicates what is returned. For example, the
method getForObject
will perform a GET, convert
the HTTP response into an object type of your choice and return that
object. The method postForLocation
will do a
POST, converting the given object into a HTTP request and return the
response HTTP Location header where the newly created object can be
found. In case of an exception processing the HTTP request, an exception
of the type RestClientException
will be
thrown, this behavior can be changed by plugging in another ResponseErrorHandler
implementation into the RestTemplate
.
Objects passed to and returned from these methods are converted to
and from HTTP messages by
HttpMessageConverter
instances.
Converters for the main mime types are registered by default, but you
can also write your own converter and register it via the
messageConverters
bean property. The default
converter instances registered with the template are
ByteArrayHttpMessageConverter
,
StringHttpMessageConverter
,
FormHttpMessageConverter
and
SourceHttpMessageConverter
. You can override
these defaults using the messageConverters
bean
property as would be required if using the
MarshallingHttpMessageConverter
.
Each method takes URI template arguments in two forms, either as a
String
variable length argument or a
Map<String,String>
. For example,
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class,"42", "21");
using variable length arguments and
Map<String, String> vars = Collections.singletonMap("hotel", "42"); String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);
using a Map<String,String>
.
To create an instance of RestTemplate
you
can simply call the default constructor. This will use standard Java
classes from the java.net
package as the underlying
implementation to create HTTP requests. This can be overridden by
specifying an implementation of
ClientHttpRequestFactory
. Spring provides
the implementation
CommonsClientHttpRequestFactory
that uses the
Jakarta Commons HttpClient
to create requests.
CommonsClientHttpRequestFactory
is configured
using an instance of
org.apache.commons.httpclient.HttpClient
which
can in turn be configured with credentials information or connection
pooling functionality.
The previous example using Jakarta Commons
HttpClient
directly rewritten to use the
RestTemplate
is shown below
uri = "http://example.com/hotels/{id}/bookings"; RestTemplate template = new RestTemplate(); Booking booking = // create booking object URI location = template.postForLocation(uri, booking, "1");
The general callback interface is
RequestCallback
and is called when the
execute method is invoked.
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor, String... urlVariables) // also has an overload with urlVariables as a Map<String, String>.
The RequestCallback
interface is
defined as
public interface RequestCallback { void doWithRequest(ClientHttpRequest request) throws IOException; }
and allows you to manipulate the request headers and write to the request body. When using the execute method you do not have to worry about any resource management, the template will always close the request and handle any errors. Refer to the API documentation for more information on using the execute method and the meaning of its other method arguments.
Objects passed to and returned from the methods
getForObject
,
postForLocation
, and
put
are converted to HTTP requests and from
HTTP responses by HttpMessageConverters
.
The HttpMessageConverter
interface is
shown below to give you a better feel for its functionality
public interface HttpMessageConverter<T> { // Indicate whether the given class is supported by this converter. boolean supports(Class<? extends T> clazz); // Return the list of MediaType objects supported by this converter. List<MediaType> getSupportedMediaTypes(); // Read an object of the given type form the given input message, and returns it. T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; // Write an given object to the given output message. void write(T t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException; }
Concrete implementations for the main media (mime) types are
provided in the framework and are registered by default with the
RestTemplate
on the client-side and with
AnnotationMethodHandlerAdapter
on the
server-side.
The implementations of
HttpMessageConverter
s are described in the
following sections. For all converters a default media type is used but
can be overridden by setting the
supportedMediaTypes
bean property
An HttpMessageConverter
implementation that can read and write Strings from the HTTP request
and response. By default, this converter supports all text media types
(text/*
), and writes with a
Content-Type
of
text/plain
.
An HttpMessageConverter
implementation that can read and write form data from the HTTP request
and response. By default, this converter reads and writes the media
type application/x-www-form-urlencoded
. Form data
is read from and written into a MultiValueMap<String,
String>
.
An HttpMessageConverter
implementation that can read and write byte arrays from the HTTP
request and response. By default, this converter supports all media
types (*/*
), and writes with a
Content-Type
of
application/octet-stream
. This can be overridden by
setting the supportedMediaTypes property, and
overriding getContentType(byte[])
.
An HttpMessageConverter
implementation that can read and write XML using Spring's
Marshaller
and
Unmarshaller
abstractions from the
org.springframework.oxm
package. This converter
requires a Marshaller
and
Unmarshaller
before it can be used.
These can be injected via constructor or bean properties. By default
this converter supports (text/xml
) and
(application/xml
).
An HttpMessageConverter
implementation that can read and write
javax.xml.transform.Source
from the HTTP
request and response. Only DOMSource
,
SAXSource
, and
StreamSource
are supported. By default, this
converter supports (text/xml
) and
(application/xml
).