There are a few methods for including external jars in your Android app. One is to manually download them and include them in your app's
libs/
folder. Another option is to use Maven for dependency management.
In order to use RestTemplate in your Android application, you must include the following Spring for Android jars in the
libs/
folder. These are available from the SpringSource
Community Downloads
page.
-
spring-android-rest-template-{version}.jar
-
spring-android-core-{version}.jar
If you are building your project with Ant, Ant will automatically include any jars located in the
libs/
folder located in the root of your project. However, in Eclipse you must manually add the jars to the Build Path. Follow these steps to add the jars to your existing Android project in Eclipse.
-
Refresh the project in Eclipse so the
libs/
folder and jars display in the Package Explorer.
-
Right-Click (Command-Click) the first jar.
-
Select the
BuildPath
submenu.
-
Select
Add to Build Path
from the context menu.
-
Repeat these steps for each jar.
Google's provided Android toolset does not include dependency management support. However, through the use of third party tools, you can use Maven to manage dependencies and build your Android app. See the
Spring for Android and Maven
section for more information. Additional dependencies may be required, depending on which HTTP Message Converters you are using within RestTemplate. See the
Message Converters
section for more information.
Add the spring-android-rest-template artifact to your classpath:
<dependency>
<groupId>org.springframework.android</groupId>
<artifactId>spring-android-rest-template</artifactId>
<version>${spring-android-version}</version>
</dependency>
The transitive dependencies are automatically imported by Maven, but they are listed here for clarity.
<dependency>
<groupId>org.springframework.android</groupId>
<artifactId>spring-android-core</artifactId>
<version>${spring-android-version}</version>
</dependency>
The four RestTemplate constructors are listed below. The default constructor does not include any message body converters. You must add a message converter when using the default constructor. If you would like to include a default set of message converters with a new RestTemplate instance, then you can pass true for the includeDefaultConverters parameter. For a list of default converters, see the HTTP Message Conversion section. Additionally, if you would like to specify a different ClientHttpRequestFactory then you can do so by passing it in to the requestFactory parameter.
RestTemplate();
RestTemplate(boolean includeDefaultConverters);
RestTemplate(ClientHttpRequestFactory requestFactory);
RestTemplate(boolean includeDefaultConverters, ClientHttpRequestFactory requestFactory);
RestTemplate provides higher level methods that correspond to each of the six main HTTP methods. These methods make it easy to invoke many RESTful services and enforce REST best practices.
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.
For more information on RestTemplate and it's associated methods, please refer to the API Javadoc
public void delete(String url, Object... urlVariables) throws RestClientException;
public void delete(String url, Map<String, ?> urlVariables) throws RestClientException;
public void delete(URI url) throws RestClientException;
public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException;
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> urlVariables) throws RestClientException;
public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException;
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... urlVariables);
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> urlVariables);
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
public HttpHeaders headForHeaders(String url, Object... urlVariables) throws RestClientException;
public HttpHeaders headForHeaders(String url, Map<String, ?> urlVariables) throws RestClientException;
public HttpHeaders headForHeaders(URI url) throws RestClientException;
public Set<HttpMethod> optionsForAllow(String url, Object... urlVariables) throws RestClientException;
public Set<HttpMethod> optionsForAllow(String url, Map<String, ?> urlVariables) throws RestClientException;
public Set<HttpMethod> optionsForAllow(URI url) throws RestClientException;
public URI postForLocation(String url, Object request, Object... urlVariables) throws RestClientException;
public URI postForLocation(String url, Object request, Map<String, ?> urlVariables);
public URI postForLocation(URI url, Object request) throws RestClientException;
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables);
public <T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables);
public <T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException;
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables);
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
public <T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;
public void put(String url, Object request, Object... urlVariables) throws RestClientException;
public void put(String url, Object request, Map<String, ?> urlVariables) throws
RestClientException;
public void put(String url, Object request, Map<String, ?> urlVariables) throws RestClientException;
Objects passed to and returned from the methods getForObject(), getForEntity(), postForLocation(), postForObject() and put() are converted to HTTP requests and from HTTP responses by HttpMessageConverter instances. The HttpMessageConverter interface is shown below to give you a better feel for its functionality.
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, MediaType mediaType);
boolean canWrite(Class<?> clazz, MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
Concrete implementations for the main media (mime) types are provided in the framework.
For performance reasons, the default RestTemplate constructor does not register any message converters. However, if you pass true to the alternate constructor, then converters for the main mime types are registered. You can also write your own converter and register it via the messageConverters property.
When using the alternate RestTemplate constructor, the default converter instances registered with the template are ByteArrayHttpMessageConverter, StringHttpMessageConverter, and ResourceHttpMessageConverter. If your app is running on Android 2.2 or later, then XmlAwareFormHttpMessageConverter and SourceHttpMessageConverter are registered, as these two message converters require javax.xml.transform.Source. On Android 2.1, this falls back to the FormHttpMessageConverter which lacks some of the XML support in the other two. See the following table for more information.
Table 2.1. Default Message Converters
Message Body ConverterInclusion Rule
ByteArrayHttpMessageConverterAlways included
StringHttpMessageConverter
ResourceHttpMessageConverter
SourceHttpMessageConverterIncluded on Android 2.2 (Froyo) or newer, where
javax.xml.transform.Source is available.
XmlAwareFormHttpMessageConverter
FormHttpMessageConverterIncluded on Android 2.1 (Eclair) and older.
SimpleXmlHttpMessageConverterIncluded if the Simple XML serializer is present.
MappingJackson2HttpMessageConverterIncluded if the Jackson 2.x JSON processor is present.
MappingJacksonHttpMessageConverterIncluded if the Jackson 1.x JSON processor is present. Jackson 2.x support takes precedence over Jackson 1.x if both versions are available on the classpath.
SyndFeedHttpMessageConverterIncluded if the Android ROME Feed Reader is present.
The following HttpMessageConverter implementations are available in Spring for Android. For all converters a default media type is used but can be overridden through the supportedMediaTypes property.
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 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>.
Extension of FormHttpMessageConverter, adding support for XML-based parts through a SourceHttpMessageConverter
An HttpMessageConverter implementation that can read and write Resource Resources. By default, this converter can read all media types. application/octet-stream is used to determine the Content-Type of written resources
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.
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 XML from the HTTP request and response using Simple Framework's Serializer. XML mapping can be customized as needed through the use of Simple's provided annotations. When additional control is needed, a custom Serializer can be injected through the Serializer property. By default, this converter reads and writes the media types application/xml, text/xml, and application/*+xml.
It is important to note that this is not a Spring OXM compatible message converter. It is a standalone implementation that enables XML serialization through Spring for Android.
Add the following dependency to your classpath to enable the SimpleXmlHttpMessageConverter.
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
<version>${simple-version}</version>
</dependency>
An HttpMessageConverter implementation that can read and write JSON using Jackson (2.x)'s ObjectMapper. JSON mapping can be customized as needed through the use of Jackson's provided annotations. When further control is needed, a custom ObjectMapper can be injected through the ObjectMapper property for cases where custom JSON serializers/deserializers need to be provided for specific types. By default this converter supports application/json.
Please note that this message converter and the GsonHttpMessageConverter both support application/json by default. Because of this, you should only add one JSON message converter to a RestTemplate instance. RestTemplate will use the first converter it finds that matches the specified mime type, so including both could produce unintended results.
Include the following dependencies in your classpath to enable the MappingJackson2HttpMessageConverter. Please note that if you are manually copying the jars into your project, you will also need to include the jackson-annotations and jackson-core jars.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
If you would prefer to use the Jackson JSON Processor instead, then include the following dependencies in your classpath to enable the MappingJacksonHttpMessageConverter. Please note that if you are manually copying the jars into your project, you will also need to include the jackson-core-asl jar.
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson-version}</version>
</dependency>
An HttpMessageConverter implementation that can read and write JSON using Google Gson's Gson class. JSON mapping can be customized as needed through the use of Gson's provided annotations. When further control is needed, a custom Gson can be injected through the Gson property for cases where custom JSON serializers/deserializers need to be provided for specific types. By default this converter supports application/json.
Please note that this message converter and the MappingJackson2HttpMessageConverter both support application/json by default. Because of this, you should only add one JSON message converter to a RestTemplate instance. RestTemplate will use the first converter it finds that matches the specified mime type, so including both could produce unintended results.
Include the following dependency in your classpath to enable the GsonHttpMessageConverter.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson-version}</version>
</dependency>
An HttpMessageConverter implementation that can read and write RSS and Atom feeds from the HTTP request and response using Android ROME Feed Reader. The data is read from and written into a com.google.code.rome.android.repackaged.com.sun.syndication.feed.synd.SyndFeed. By default, this converter supports application/rss+xml and application/atom+xml.
Add the following dependencies to your classpath to enable the SyndFeedHttpMessageConverter, RssChannelHttpMessageConverter, or AtomFeedHttpMessageConverter. This library depends on a forked version of JDOM to work on Android 2.1 and earlier. The JDOM library addresses a bug in the Android XML parser.
<dependency>
<groupId>com.google.code.android-rome-feed-reader</groupId>
<artifactId>android-rome-feed-reader</artifactId>
<version>${android-rome-version}</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>${jdom-fork-version}</version>
</dependency>
The Android ROME Feed Reader is not available through Maven Central. When using Maven, you will need to include the following repository in your POM.
<repository>
<id>android-rome-feed-reader-repository</id>
<name>Android ROME Feed Reader Repository</name>
<url>https://android-rome-feed-reader.googlecode.com/svn/maven2/releases</url>
</repository>
An HttpMessageConverter implementation that can read and write RSS feeds from the HTTP request and response using Android ROME Feed Reader. The data is read from and written into a com.google.code.rome.android.repackaged.com.sun.syndication.feed.rss.Channel. By default, this converter supports application/rss+xml.
The SyndFeedHttpMessageConverter provides a higher level of abstraction around RSS and Atom feeds, the RssChannelHttpMessageConverter is not included in the default set of message converters when you create a new RestTemplate instance. If you prefer to use this message converter then you have to manually add it to the RestTemplate instance.
See the SyndFeedHttpMessageConverter section for information about the required Android ROME Feed Reader dependencies.
An HttpMessageConverter implementation that can read and write Atom feeds from the HTTP request and response using Android ROME Feed Reader. The data is read from and written into a com.google.code.rome.android.repackaged.com.sun.syndication.feed.atom.Feed. By default, this converter supports application/atom+xml.
Because the SyndFeedHttpMessageConverter provides a higher level of abstraction around RSS and Atom feeds, the AtomFeedHttpMessageConverter is not included in the default set of message converters when you create a new RestTemplate instance. If you prefer to use this message converter then you have to manually add it to the RestTemplate instance.
See the SyndFeedHttpMessageConverter section for information about the required Android ROME Feed Reader dependencies.
Using RestTemplate, it's easy to invoke RESTful APIs. Below are several usage examples that illustrate the different methods for making RESTful requests.
All of the following examples are based on a sample Android application. You can retrieve the source code for the sample app with the following command:
$ git clone git://github.com/SpringSource/spring-android-samples.git
The following example shows a query to google for the search term "SpringSource".
String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
String result = restTemplate.getForObject(url, String.class, "SpringSource");
Gzip compression can significantly reduce the size of the response data being returned in a REST request. Gzip must be supported by the web server to which the request is being made. By setting the content coding type of the Accept-Encoding header to gzip, you are requesting that the server respond using gzip compression. If gzip is available, or enabled on the server, then it should return a compressed response. RestTemplate checks the Content-Encoding header in the response to determine if, in fact, the response is gzip compressed. At this time, RestTemplate only supports the gzip content coding type in the Content-Encoding header. If the response data is determined to be gzip compressed, then a GZIPInputStream is used to decompress it.
The following example shows how to request a gzip compressed response from the server.
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAcceptEncoding(ContentCodingType.GZIP);
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
One thing to note, is that when using the J2SE facilities with the SimpleClientHttpRequestFactory, Gingerbread and newer automatically set the Accept-Encoding header to request gzip responses. This is built in functionality of newer versions of Android. If you desire to disable gzip, then you must set the identity value in the header.
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAcceptEncoding(ContentCodingType.IDENTITY);
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
Suppose you have defined a Java object you wish to populate from a RESTful web request that returns JSON content.
Define your object based on the JSON data being returned from the RESTful request:
public class Event {
private Long id;
private String title;
public Long getId() {
return id;
public void setId(Long id) {
this.id = id;
public String getTitle() {
return title;
public String setTitle(String title) {
this.title = title;
Make the REST request:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Event[] events = restTemplate.getForObject(url, Event[].class);
You can also set the Accept header for the request:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
ResponseEntity<Event[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Event[].class);
Event[] events = responseEntity.getBody();
Alternatively, you can use the GsonHttpMessageConverter for JSON marshaling. The following repeats the same request, utilizing Gson.
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
ResponseEntity<Event[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Event[].class);
Event[] events = responseEntity.getBody();
Using the same Java object we defined earlier, we can modify the requests to retrieve XML.
Define your object based on the XML data being returned from the RESTful request. Note the annotations used by Simple to marshal the object:
@Root
public class Event {
@Element
private Long id;
@Element
private String title;
public Long getId() {
return id;
public void setId(Long id) {
this.id = id;
public String getTitle() {
return title;
public String setTitle(String title) {
this.title = title;
To marshal an array of events from xml, we need to define a wrapper class for the list:
@Root(name="events")
public class EventList {
@ElementList(inline=true)
private List<Event> events;
public List<Event> getEvents() {
return events;
public void setEvents(List<Event> events) {
this.events = events;
Make the REST request:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new SimpleXmlHttpMessageConverter());
EventList eventList = restTemplate.getForObject(url, EventList.class);
You can also specify the Accept header for the request:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new MediaType("application","xml")));
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new SimpleXmlHttpMessageConverter());
ResponseEntity<EventList> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, EventList.class);
EventList eventList = responseEntity.getBody();
POST a Java object you have defined to a RESTful service that accepts JSON data.
Define your object based on the JSON data expected by the RESTful request:
public class Message
private long id;
private String subject;
private String text;
public void setId(long id) {
this.id = id;
public long getId() {
return id;
public void setSubject(String subject) {
this.subject = subject;
public String getSubject() {
return subject;
public void setText(String text) {
this.text = text;
public String getText() {
return text;
Make the REST request. In this example, the request responds with a string value:
Message message = new Message();
message.setId(555);
message.setSubject("test subject");
message.setText("test text");
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
String response = restTemplate.postForObject(url, message, String.class);
You can also specify the Content-Type header in your request:
Message message = new Message();
message.setId(555);
message.setSubject("test subject");
message.setText("test text");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(new MediaType("application","json"));
HttpEntity<Message> requestEntity = new HttpEntity<Message>(message, requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
String result = responseEntity.getBody();
The following is a basic example of loading an RSS feed:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new SyndFeedHttpMessageConverter());
SyndFeed = restTemplate.getForObject(url, SyndFeed.class);
It is possible that you need to adjust the Media Type associated with the SyndFeedHttpMessageConverter. By default, the converter is associated with application/rss+xml and application/atom+xml. An RSS feed might instead have a media type of text/xml, for example. The following code illustrates how to set the media type.
SyndFeedHttpMessageConverter syndFeedConverter = new SyndFeedHttpMessageConverter();
syndFeedConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_XML));
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(syndFeedConverter);
SyndFeed feed = restTemplate.getForObject(url, SyndFeed.class);
This example illustrates how to populate the HTTP Basic Authentication header with the username and password. If the username and password are accepted, then you will receive the response from the request. If they are not accepted, then the server is supposed to return an HTTP 401 Unauthorized response. Internally, RestTemplate handles the response, then throws an HttpClientErrorException. By calling getStatusCode() on this exception, you can determine the exact cause and handle it appropriately.
HttpAuthentication authHeader = new HttpBasicAuthentication(username, password);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAuthorization(authHeader);
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
try {
ResponseEntity<Message> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
return response.getBody();
} catch (HttpClientErrorException e) {
Log.e(TAG, e.getLocalizedMessage(), e);