The RestTemplate class in Spring Framework is a synchronous HTTP client for making HTTP requests to consume RESTful web services. It exposes a simple and easy-to-use template method API for sending an HTTP request and handling the HTTP response.
The RestTemplate class also provides aliases for all supported HTTP request methods, such as GET, POST, PUT, DELETE, and OPTIONS.
In this tutorial, we will learn how to use the Spring REST client — RestTemplate — for sending HTTP requests in a Spring Boot application.
Dependencies
Since the RestTemplate class is a part of the Spring Web project, we only need the spring-boot-starter-web
dependency. Add the following dependency to your Gradle project's build.gradle
file:
implementation 'org.springframework.boot:spring-boot-starter-web'
If you are using Maven, add the following dependency to your pom.xml
file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
GET Request
Let's start with a simple example to retrieve a list of posts using RestTemplate's getForObject()
method:
RestService.java
@Service
public class RestService {
private final RestTemplate restTemplate;
public RestService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
public String getPostsPlainJSON() {
String url = "https://jsonplaceholder.typicode.com/posts";
return this.restTemplate.getForObject(url, String.class);
}
}
Notice the response returned by the getForObject()
method. It is a plain JSON string. We can easily parse this JSON string into an object using Jackson.
Get Response as Object
We can also map the response directly to a model class. Let us first create a model class:
Post.java
public class Post implements Serializable {
private int userId;
private int id;
private String title;
private String body;
// getters and setters
}
Now we can simply use the Post
class as response type in getForObject()
method:
public Post[] getPostsAsObject() {
String url = "https://jsonplaceholder.typicode.com/posts";
return this.restTemplate.getForObject(url, Post[].class);
}
URL Parameters
If you want to pass the query parameters, just append them to the URL:
String url = "https://jsonplaceholder.typicode.com/posts?userId=2";
Another way is to use placeholders in the URL for parameters:
public Post getPostWithUrlParameters() {
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
return this.restTemplate.getForObject(url, Post.class, 1);
}
Response Handing
If you want to manipulate the response (like checking HTTP status code), use the getForEntity()
method like below:
public Post getPostWithResponseHandling() {
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
ResponseEntity<Post> response = this.restTemplate.getForEntity(url, Post.class, 1);
if(response.getStatusCode() == HttpStatus.OK) {
return response.getBody();
} else {
return null;
}
}
Custom Request Headers
If you want to set the request headers like content-type
, accept
, or any custom header, use the generic exchange()
method:
public Post getPostWithCustomHeaders() {
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
// create headers
HttpHeaders headers = new HttpHeaders();
// set `accept` header
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// set custom header
headers.set("x-request-source", "desktop");
// build the request
HttpEntity request = new HttpEntity(headers);
// use `exchange` method for HTTP call
ResponseEntity<Post> response = this.restTemplate.exchange(url, HttpMethod.GET, request, Post.class, 1);
if(response.getStatusCode() == HttpStatus.OK) {
return response.getBody();
} else {
return null;
}
}
Quick Guide: Check out RestTemplate GET Request with Parameters and Headers for more GET request examples.
POST Request
A POST request is used to create a new resource. The RestTemplate class offers several template methods like postForObject()
, postForEntity()
, and postForLocation()
for making POST request.
The first two methods are similar to what we discussed above for the response format. The last method returns the location of the newly created resource instead of the complete resource.
Let us make use of the postForEntity()
method to create a new post:
public Post createPost() {
String url = "https://jsonplaceholder.typicode.com/posts";
// create headers
HttpHeaders headers = new HttpHeaders();
// set `content-type` header
headers.setContentType(MediaType.APPLICATION_JSON);
// set `accept` header
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// create a map for post parameters
Map<String, Object> map = new HashMap<>();
map.put("userId", 1);
map.put("title", "Introduction to Spring Boot");
map.put("body", "Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications.");
// build the request
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(map, headers);
// send POST request
ResponseEntity<Post> response = this.restTemplate.postForEntity(url, entity, Post.class);
// check response status code
if (response.getStatusCode() == HttpStatus.CREATED) {
return response.getBody();
} else {
return null;
}
}
Alternatively, we can also use the postForObject()
method to create a new post:
public Post createPostWithObject() {
String url = "https://jsonplaceholder.typicode.com/posts";
// create headers
HttpHeaders headers = new HttpHeaders();
// set `content-type` header
headers.setContentType(MediaType.APPLICATION_JSON);
// set `accept` header
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// create a post object
Post post = new Post(1, "Introduction to Spring Boot",
"Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications.");
// build the request
HttpEntity<Post> entity = new HttpEntity<>(post, headers);
// send POST request
return restTemplate.postForObject(url, entity, Post.class);
}
Quick Guide: Check out RestTemplate POST Request with JSON and Headers for more POST request examples.
PUT Request
The RestTemplate class provides the put()
method that can be used to update a resource:
public void updatePost() {
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
// create headers
HttpHeaders headers = new HttpHeaders();
// set `content-type` header
headers.setContentType(MediaType.APPLICATION_JSON);
// set `accept` header
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// create a post object
Post post = new Post(4, "New Title", "New Body");
// build the request
HttpEntity<Post> entity = new HttpEntity<>(post, headers);
// send PUT request to update post with `id` 10
this.restTemplate.put(url, entity, 10);
}
The put()
method does not return anything. If you want to process the response, use the generic exchange()
method instead:
public Post updatePostWithResponse() {
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
// create headers
HttpHeaders headers = new HttpHeaders();
// set `content-type` header
headers.setContentType(MediaType.APPLICATION_JSON);
// set `accept` header
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// create a post object
Post post = new Post(4, "New Title", "New Body");
// build the request
HttpEntity<Post> entity = new HttpEntity<>(post, headers);
// send PUT request to update post with `id` 10
ResponseEntity<Post> response = this.restTemplate.exchange(url, HttpMethod.PUT, entity, Post.class, 10);
// check response status code
if (response.getStatusCode() == HttpStatus.OK) {
return response.getBody();
} else {
return null;
}
}
DELETE Request
To delete an existing resource, you can use the delete()
method:
public void deletePost() {
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
// send DELETE request to delete post with `id` 10
this.restTemplate.delete(url, 10);
}
HEAD Request
The RestTemplate class offers headForHeaders()
method to retrieve headers:
public HttpHeaders retrieveHeaders() {
String url = "https://jsonplaceholder.typicode.com/posts";
// send HEAD request
return this.restTemplate.headForHeaders(url);
}
OPTIONS Request
Let us use the optionsForAllow()
method to get a list of all supported HTTP operations:
public Set<HttpMethod> allowedOperations() {
String url = "https://jsonplaceholder.typicode.com/posts";
// send HEAD request
return this.restTemplate.optionsForAllow(url);
}
Error Handling
If there is an error during the request execution or the server returns a non-successful HTTP error (4xx or 5xx), RestTemplate will throw an exception. You can catch the HttpStatusCodeException
in the catch
block to get the response body and headers:
public String unknownRequest() {
try {
String url = "https://jsonplaceholder.typicode.com/404";
return this.restTemplate.getForObject(url, String.class);
} catch (HttpStatusCodeException ex) {
// raw http status code e.g `404`
System.out.println(ex.getRawStatusCode());
// http status code e.g. `404 NOT_FOUND`
System.out.println(ex.getStatusCode().toString());
// get response body
System.out.println(ex.getResponseBodyAsString());
// get http headers
HttpHeaders headers= ex.getResponseHeaders();
System.out.println(headers.get("Content-Type"));
System.out.println(headers.get("Server"));
}
return null;
}
Quick Guide: Learn more about handling errors while using the RestTemplate in a Spring Boot application.
RestTemplate Connection Timeout
There are two types of timeouts: connection timeout and read timeout. By default, RestTemplate has infinite timeouts.
But we can change this behavior by using the RestTemplateBuilder
class for setting the connection and read timeouts:
public RestService(RestTemplateBuilder restTemplateBuilder) {
// set connection and read timeouts
this.restTemplate = restTemplateBuilder
.setConnectTimeout(Duration.ofSeconds(500))
.setReadTimeout(Duration.ofSeconds(500))
.build();
}
Source code: Download the complete source code from GitHub available under MIT license.
Conclusion
That's all for using Spring Framework's RestTemplate class to call remote RESTful web services in a Spring Boot application. We talked about almost all HTTP verbs and used RestTemplate to make requests for all of them.
If you are interested in learning more, check out the processing JSON data in Spring Boot guide. It will introduce you to Jackson, which is used with RestTemplate for parsing unknown JSON data.
Read Next: RestTemplate Basic Authentication Example
✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.