This article will explain what is Spring boot RestTemplate, its use with GET, POST, PUT, DELETE request examples and its various methods.

What is RestTemplate

Spring boot RestTemplate is a client provided by Spring to invoke HTTP URLs and get their response as a JSON string or directly as java objects.
RestTemplate is a synchronous client that supports all common HTTP requests such as GET, POST, PUT, PATCH and DELETE.
It is a web service consumer which is used to call third party apis or URLs or consume REST API from a Spring application.

As per Spring documentation for RestTemplate,

Synchronous client to perform HTTP requests, exposing a simple, template method API over underlying HTTP client libraries such as the JDK HttpURLConnection, Apache HttpComponents, and others.

Spring boot RestTemplate dependency

For using RestTemplate, include following dependency for Spring boot web in your project as per the build tool.

Maven

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   <version>3.2.1</version>
</dependency>

Gradle

implementation 'org.springframework.boot:spring-boot-starter-web:3.2.1'

RestTemplate is a class that resides in org.springframework.web.client package. It is implicitly imported in any Spring boot web mvc application since both share the same dependency.

RestTemplate can be used directly by creating its object using new.

Once the object is created, it can be used to hit any external api URL to fetch data.

There is another method to create an object of RestTemplate using Spring configuration using RestTemplateBuilder.

@Component
public class RestClient {

  RestTemplate template;
  
  public Template(RestTemplateBuilder builder) {
    this.template = builder.build();
  }
}

Spring boot RestTemplate GET example
HTTP GET requests are used for fetching data from a given URL.
RestTemplate provides following methods that fetch data using GET method.

This article uses JsonPlaceholder, a fake REST api for its examples.

1. getForObject()

This method accepts a URL and the type of Object that you want the response, this should be of type java.lang.Class. It returns an object of same type as the type of Class object.
Syntax for this method is

T obj = getForObject(URL, Class<T>)

where T is generic type.

There are three overloaded versions of this method. The other two take an additional argument for supplying variables in the URL.
Using getForObject() for fetching data from an external URL is given below.

RestTemplate template = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts";
// fetch response in a string object
String response = template.getForObject(url, String.class);
System.out.println(response);

Note that in this example we are using getForObject() method with the URL that we want to fetch data from and the type to which it should be casted.
For this example, it is a String as you can see from the second argument.
This prints

{
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  }

Response data has been truncated for clarity.

You can convert this json response to a java object manually but instead, getForObject() can do it for you automatically.

POJO

Java class that we will be using in all examples that require a class type and object is given below.
This class should have fields or instance variables with same name as the keys in json response.

public class Post {
   
   private Integer userId;

   private Integer id;

   private String description;

   private String title;

   private String body; 

   // gettters and setters

}

Now, in place of String in getForObject(), this class will be used.

RestTemplate template = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts/1";
// fetch response as a post object
Post post = template.getForObject(url, Post.class);
System.out.println(post);

Note that in this example, the return value from getForObject() is an object of type Post . All its fields will automatically be populated with values returned from response.

2. getForEntity()

This method accepts a URL and returns an object of ResponseEntity.
With ResponseEntity, you have access to the body of actual response and status code of response.
When using ResponseEntity, you need to call its getBody() method to get the required response data. Example,

RestTemplate rest = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts?userId=1";
ResponseEntity<Post[]> entity = rest.getForEntity(url, Post[].class);
Post[] posts = entity.getBody();

Note that the URL returns multiple posts, so the type of ResponseEntity is a Post[] and the return type of getBody() will also be the same.
If the URL returns a single post, then the type of ResponseEntity and return type from getBody() will be a Post object.

Spring boot RestTemplate query parameters

URL that you want to access might have some query parameters. Example,

https://jsonplaceholder.typicode.com/posts?postId=1&userId=2

Here, postId and userId are called query parameters.
getForObject() has two overloaded versions which allow to replace query parameters with values dynamically.

One of these accepts a java.util.Map as a third parameter. Key and value of this map correspond to the name of query parameter that needs to be replaced and its value respectively.

Note that the values of query parameters in the URL should be enclosed between curly braces as

https://jsonplaceholder.typicode.com/posts?postId={pId}&userId={uId}

Example of these methods is given below.

RestTemplate rest = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts?userId={uid}";
// initialize params map
Map<String, String> params = new HashMap<>();
// add entry for query parameter
params.put("uid", "1");
// fetch response as a post object
Post[] response = rest.getForObject(url, Post[].class, params);
System.out.println(response[0].toString());

In the above piece of code, a map is created whose keys are the ones that need to be replaced in the URL.

Other overloaded method accepts an Object array as the third argument.
Values from this array are replaced with the values of query parameters in the order in which they appear from left to right.

Thus, above example may be modified as

RestTemplate rest = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts?userId={uid}";
// replace query params with values from array
Post[] response = rest.getForObject(url, Post[].class, new Object[]{1});
System.out.println(response[0].toString());

Similar to getForObject(), query parameters can also be replaced with getForEntity() using its overloaded methods that accepts a Map and an array as shown below.

RestTemplate rest = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts?userId={uid}";
// parameter value map
Map<String, String> params = new HashMap<>();
params.put("uid", "1");
System.out.println("Fetching posts for user id: 1"); 
// fetch response
ResponseEntity<Post[]> entity = rest.getForEntity(
                                     url, Post[].class, params);
Post[] posts = entity.getBody();
System.out.println(posts[0].toString());

System.out.println("Fetching posts for user id: 2");      
// use array for parameter value
entity = rest.getForEntity(url, Post[].class, new Object[] {2});
posts = entity.getBody();
System.out.println(posts[0].toString());

This prints

Fetching posts for user id: 1
Post [userId=1, id=1, title=sunt aut facere repellat provident occaecati excepturi optio reprehenderit]
Fetching posts for user id: 2
Post [userId=2, id=11, title=et ea vero quia laudantium autem]

Notice how map and array successfully replaced the URL parameters with values.
getForEntity() can also be used to fetch response as a String. In this case, the type of ResponseEntity object and return value of getBody() will be a String as shown below.

RestTemplate rest = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts?userId={uid}";
// parameter value map
Map<String, String> params = new HashMap<>();
params.put("uid", "1");
System.out.println("Fetching data from user id: 1"); 
// fetch response as string
ResponseEntity<String> entity = rest.getForEntity(
                                     url, String.class, params);
String posts = entity.getBody();
System.out.println(posts);

Spring boot RestTemplate POST example

RestTemplate offers postForEntity(), postForObject(), postForLocation() methods for executing an HTTP POST request for creating a resource at some URL.

Description and difference between these is

1. postForEntity()

Accepts the URL, object to post and the class type of the object and returns the response as an object of ResponseEntity.
Response content can be retrieved using getBody() method.

2. postForObject()

Accepts the URL, object to post and the class type of the object and returns the response as the object of the same class type as the third parameter.

3. postForLocation()

Accepts the URL, object to post and the class type of the object and returns the URL at which the new resource is created.
Typically, it returns the value stored in the Location header of response.

All of these have overloaded methods that accept a Map and object array that allow to replace URL parameters with their values similar to that we saw in getForObject() and getForEntity() methods above.

Examples of these methods are given below.

RestTemplate rest = new RestTemplate();
// define URL to post
String url = "https://jsonplaceholder.typicode.com/posts";
// create object to post
Post post = new Post();
post.setId(20);
post.setTitle("Demo");
post.setUserId("1");
    
// post using postForEntity()
ResponseEntity<Post> response = rest.postForEntity(
                                     url, post, Post.class);
System.out.println("Response with postForEntity()...");
System.out.println(response.getBody().toString());
System.out.println("Response code:: " + response.getStatusCodeValue());
// post using postForObject()    
Post postResponse = rest.postForObject(url, post, Post.class);
System.out.println("\nResponse with postForObject()...");
System.out.println(postResponse.toString());
    
// post using postForLocation()
URI uri = rest.postForLocation(url, post, Post.class);
System.out.println("\nResponse with postForLocation()...");
System.out.println(uri.toString());

When you run this application, it will print

Response with postForEntity()…
Post [userId=1, id=101, title=Demo]
Response code:: 201

Response with postForObject()…
Post [userId=1, id=101, title=Demo]

Response with postForLocation()…
http://jsonplaceholder.typicode.com/posts/101

Spring boot RestTemplate PUT method

HTTP PUT method is used for updating a resource.
RestTemplate provides put() method for this.

There are three overloaded versions of put().
One that takes the URL and object as parameters,
other takes URL, object and a map for URL parameters,
and third accepts a URL, object and an Object array.

Examples of all these methods are given below.

RestTemplate rest = new RestTemplate();
// define URL
String url = "https://jsonplaceholder.typicode.com/posts/1";
// create object to put 
Post post = new Post(); 
post.setId(20); 
post.setTitle("Demo"); 
post.setUserId("2");
System.out.println("PUT with plain URL");    
rest.put(url, post); 
System.out.println("Resource updated");

// define paramterized URL
String paramUrl = "https://jsonplaceholder.typicode.com/posts/{pId}";
// create map for URL parameters
Map<String, Integer> params = new HashMap<String, Integer>();
params.put("pId", 1);
System.out.println("PUT with parameterized URL");
rest.put(paramUrl, post, params);
System.out.println("Resource updated");

System.out.println("PUT with parameterized URL");
// put with object array for parameters
rest.put(paramUrl, post,new Object[] {1});
System.out.println("Resource updated");

This prints

PUT with plain URL
Resource updated
PUT with parameterized URL
Resource updated
PUT with parameterized URL
Resource updated

put() method does not return any value.
But sometimes, you might want access to the response code or the updated entity returned by the server.

For this, exchange() method of RestTemplate may be used. exchange() method accepts the URL, HTTP method to invoke, the entity to be updated and the class type of entity.

exchange() returns an object of ResponseEntity which contains the response returned by the server in its body as well as the response code and response headers. Example,

String url = "https://jsonplaceholder.typicode.com/posts/1";
ResponseEntity<Post> exchange = rest.exchange(
                                    url, HttpMethod.PUT, 
                                    new HttpEntity<Post>(post), 
                                    Post.class);
System.out.println("Response:: " + exchange.getBody().toString());
System.out.println("Response code:: " + exchange.getStatusCodeValue());

This prints

Response:: Post [userId=2, id=1, title=Demo]Response code:: 200

Spring boot RestTemplate DELETE

HTTP DELETE operation is used for deleting a resource from a given URL.

Spring boot RestTemplate provides delete() method for this.
As with the other methods, RestTemplate has three overloaded methods for delete().
Examples of delete() are given below.

RestTemplate rest = new RestTemplate();
// define URL
String url = "https://jsonplaceholder.typicode.com/posts/1";

System.out.println("DELETE with plain URL");    
rest.delete(url); 
System.out.println("Resource deleted");

// define paramterized URL
String paramUrl = "https://jsonplaceholder.typicode.com/posts/{pId}";
// create map for URL parameters
Map<String, Integer> params = new HashMap<String, Integer>();
params.put("pId", 1);
System.out.println("DELETE with parameterized URL");
rest.put(paramUrl, params);
System.out.println("Resource deleted");

System.out.println("DELETE` with parameterized URL");
// put with object array for parameters
rest.put(paramUrl, new Object[] {1});
System.out.println("Resource deleted");

Output is

DELETE with plain URL
Resource deleted
DELETE with parameterized URL
Resource deleted
DELETE with parameterized URL
Resource deleted

Similar to put(), delete() does not return any value.
To gain access to the response code,  use exchange() method as shown below.

String url = "https://jsonplaceholder.typicode.com/posts/1";
ResponseEntity<Void> exchange = rest.exchange(
                                     url, HttpMethod.DELETE, null, 
                                     Void.class);
System.out.println("Response code:: " + exchange.getStatusCodeValue());

Note that the entity in this case is null since we do not need to send anything to the server and the class type is Void since the server does not return anything for DELETE.

Getting headers

RestTemplate allows you to get response headers using its headForHeaders() method.
This method returns an object of HttpHeaders which has all the headers that are returned in response.

Some of such headers are Date, Content-Type, Content-Length etc.
HttpHeaders contains methods to retrieve all header values.
headForHeaders() accepts a URL as argument while its overloaded variants also accept a Map and an Object array for parameterized URL. Example,

String url = "https://jsonplaceholder.typicode.com/posts/1";
HttpHeaders headers = rest.headForHeaders(url);
System.out.println("Content-Type header value:: " + 
                                  headers.getContentType().toString());
System.out.println("Cache-Control header value:: " + 
                                  headers.getCacheControl());

which prints

Content-Type header value:: application/json;charset=utf-8
Cache-Control header value:: max-age=43200

headForHeaders() will execute HTTP HEAD request internally.

Find allowed request types

Spring boot RestTemplate has a provision to check for permissible request types exposed on a specific URL using its optionsForAllow() method.
This method accepts a URL and returns a Set of type HttpMethod containing allowed request types.
Note that this method fires HTTP OPTIONS request to the given URL. If OPTIONS request is not exposed, you would get a 405 – Method not allowed error.

Example, to check which request types are allowed for Spring official site, below code can be used.

RestTemplate rest = new RestTemplate();
Set<HttpMethod> optionsForAllow = rest.optionsForAllow(
                                    "https://spring.io");
System.out.println(optionsForAllow);

This prints

[GET, HEAD, OPTIONS]

which means that you can only execute above requests to this URL.

In this article, we looked at using spring boot RestTemplate to execute HTTP requests to
1. Fetch using getForObject() and getForEntity(),
2. Create with postForObject() and postForEntity() methods,
3. Update data with put() method,
4. Delete with delete(),
5. Get response headers with headForHeaders(),
6. Determine exposed methods with optionsForAllow() method.

Hope the article was useful !!!