In this article, we will learn how to use Spring RestTemplate. Let’s get started.
Table of contents
- Introduction to Spring RestTemplate
- Some useful methods that RestTemplate supports
- Some steps use for utilizing Spring RestTemplate
- Source code
- Benefits and Drawbacks
- Understanding about some useful classes for utilizing RestTemplate
- Some problems when using Spring RestTemplate
- Wrapping up
Introduction to Spring RestTemplate
Spring RestTemplate is a part of spring-web module that was introduced in Spring 3. We have some interesting information that we have to jot down:
-
It is a blocking and synchronous HttpClient that exposes a simple, template method API over underlying HTTP Client libraries such as JDK HttpURLConnection, Apache HttpComponents, …
Spring RestTemplate is an above layer of the Http client, it will tackle the problem of the transformation from JSON or XML to Java objects.
The Http client takes care of all low-level details of communication via HTTP.
-
It supports Restful webservices with only Http protocol, not Https protocol.
-
It will be deprecated in the future since we have WebClient that support reactive programming, non-blocking HttpClient in Spring boot 2 or Spring 5 or later.
RestTemplate simplifies communication with HTTP services, and program code can provide it with URLs and extract results. It uses JDK’s HttpURLConnection by default to communicate, but we can switch to different HTTP sources through RestTemplate.setRequestFactory(): Apache HttpComponents, Netty, OkHttp, and so on.
Some useful methods that RestTemplate supports
-
getForObject() : It retrieves an entity using HTTP GET method on the given URL.
-
exchange() : Executes the HTTP method for the given URI. It returns ResponseEntity. It can communicate using any HTTP method.
-
headForHeaders() : Retrieves all headers. It uses HTTP HEAD method.
-
getForEntity() : It retrieves an entity by using HTTP GET method for the given URL. It returns ResponseEntity.
-
delete() : Deletes the resources at the given URL. It uses HTTP DELETE method.
-
put(): It creates new resource or update for the given URL using HTTP PUT method.
-
postForObject(): It creates new resource using HTTP POST method and returns an entity.
-
postForLocation(): It creates new resource using HTTP POST method and returns the location of created new resource.
-
postForEntity(): It creates news resource using HTTP POST method to the given URI template. It returns ResponseEntity.
Some steps use for utilizing Spring RestTemplate
-
We use HttpHeaders class to fill some key-values into our http header.
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Authorization", "Bearer ..."); // include the other parameters of header.
-
Normally, we will use HttpEntity to wrap all request body and all parameters of http header.
HttpEntity <String> entity = new HttpEntity<String>(headers); // or String bodyData = ""; HttpEntity<String> httpEntity = new HttpEntity<String>(bodyData, headers);
-
Send request.
-
The common way to send request is to use exchange() method and use HttpMethod class that define all request methods we need.
-
With get request, we can use getForEntity() method or getForObject() method.
-
With post request, use postForObject(), postForEntity(), postForLocation() methods.
-
With put request, use put() method.
-
With delete request, use delete() method.
-
To get all headers information, use headForHeaders() method.
-
Source code
In order to understand how to implement code by using Spring RestTemplate, we can check out source code in Spring RestTemplate Utils.
Benefits and Drawbacks
-
Benefits
-
Spring RestTemplate provides many functionality for interact with Rest client. It deals with JSON/XML transformation of entities, …
-
Spring RestTemplate is a higher-level abstraction than Apache HttpClient. By default, Spring RestTemplate uses Apache HttpClient internally. We can use other implementation with configuring ClientHttpRequestFactory class.
-
RestTemplate is thread-safe once constructed, and that we can use callbacks to customize its operations.
-
-
Drawbacks
-
It takes so much time when we have multiple user access.
Under the hood, RestTemplate uses the Java Servlet API, which is based on the thread-per-request model. The thread will block until the web client receives the response.
When we have multiple user, our application will create multiple threads, which will exhaust the thread pool or occupy all the available memory.
-
Degrade our application’s performance.
-
Understanding about some useful classes for utilizing RestTemplate
-
RequestCallback class
@FunctionalInterface public interface RequestCallback { void doWithRequest(ClientHttpRequest var1) throws IOException; }
-
ResponseExtractor class
According to the ResponseExtractor’s document we have its definition:
@FunctionalInterface public interface ResponseExtractor<T> { @Nullable T extractData(ClientHttpResponse var1) throws IOException; }
The extractData() method is used to extract data from the given ClientHttpResponse and return it.
Take a closer look at ClientHttpResponse class, we can find that:
public interface ClientHttpResponse extends HttpInputMessage, Closeable { HttpStatus getStatusCode() throws IOException; int getRawStatusCode() throws IOException; String getStatusText() throws IOException; void close(); } public interface HttpInputMessage extends HttpMessage { InputStream getBody() throws IOException; }
It means that its method will be called each time we receive stream data that probably assuming that it has BUFFER_SIZE = 4096 or like that. Then, to get data under InputStream, we only need to call var1.getBody(). Finally, we will read data from InputStream, then convert it to our format.
But the getForObject() and getForEntity() methods of RestTemplate load the entire response in memory. This is not suitable for downloading large files since it can cause out of memory exceptions. So, to deal with this problem, we can use ResponseExtractor class as argument of execute() method of RestTemplate.
RequestCallback requestCallback = request -> request.getHeaders() .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL)); ResponseExtractor<Void> responseExtractor = response -> { Path path = Paths.get("some/path"); Files.copy(response.getBody(), path); return null; }; restTemplate.execute(URI.create("www.something.com"), HttpMethod.GET, requestCallback, responseExtractor);
Some problems when using Spring RestTemplate
-
Error while extracting response for type [class java.lang.String] and content type [application/json]
The main problem here is content type [text/html;charset=iso-8859-1] received from the service, however the real content type should be application/json;charset=iso-8859-1
In order to overcome this you can introduce custom message converter. and register it for all kind of responses (i.e. ignore the response content type header). Just like this:
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>(); //Add the Jackson Message converter MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); // Note: here we are making this converter to process any kind of response, // not only application/*json, which is the default behaviour converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL)); messageConverters.add(converter); restTemplate.setMessageConverters(messageConverters);
Wrapping up
-
Spring RestTemplate that uses MessageConverter internally. So we need to set this property in the RestTemplate bean.
-
Spring supports multiple http client libraries through its ClientHttpRequestFactory abstraction:
- Apache HttpComponents HttpClient
- Netty4
- OkHttp
- OkHttp3
- Standard JDK calls
Refer:
https://www.baeldung.com/spring-webclient-resttemplate
https://github.com/spring-framework-guru/sfg-blog-posts/tree/master/resttemplate
https://springframework.guru/using-resttemplate-with-apaches-httpclient/
https://www.journaldev.com/17096/spring-resttemplate-example
https://springframework.guru/using-resttemplate-in-spring/
Error Handling in RestTemplate
https://www.baeldung.com/spring-rest-template-error-handling
Some ways to download file in Spring boot
https://memorynotfound.com/spring-mvc-download-file-examples/
https://memorynotfound.com/spring-mvc-file-upload-example-validator/
https://www.devglan.com/spring-boot/spring-boot-file-upload-download
https://www.baeldung.com/spring-resttemplate-download-large-file
https://o7planning.org/en/11765/spring-boot-file-download-example - Useful link about how to download file when using InputStreamResource, ByteArrayResource, or set properties on HttpServletResponse