Configuration
About
RestTemplate is a central class in Spring that allows applications to make HTTP calls to external services in a simple and declarative way. However, just using new RestTemplate() is rarely enough. In real-world applications, RestTemplate needs proper configuration to handle timeouts, error handling, authentication, message conversion, and performance tuning.
Creating and Registering a RestTemplate Bean
The best practice is to create a single RestTemplate bean and inject it wherever needed.
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}Using RestTemplateBuilder allows us to apply global settings such as timeouts, interceptors, and message converters.
Setting Timeouts
Timeouts are a critical part of robust system design. They help prevent our application from hanging indefinitely when a remote service is slow, overloaded, or unresponsive.
In enterprise applications, we should never rely on the default timeout settings, as they are often unbounded or too generous.
Types of Timeouts We Should Configure
In the context of RestTemplate, we typically configure two timeouts
Connection Timeout
Time allowed to establish the TCP connection to the target server.
Read Timeout
Time to wait for the response after sending the request. If the server is slow to respond or never responds, this will kick in.
Optional (depending on request factory)
Connection Request Timeout
Time to wait for a connection from the connection pool (for pooled HTTP clients). Useful when we are reusing HTTP connections.
1. Using SimpleClientHttpRequestFactory
This is the default and simplest HTTP request factory provided by Spring. It directly uses the java.net.HttpURLConnection under the hood.
Characteristics
Lightweight and easy to set up.
Good for basic use cases with low concurrency.
No support for connection pooling.
Limited to blocking I/O operations.
Best suited for small applications, internal tooling, or test utilities.
When to Use
When building non-critical or internal apps with low request volume.
In situations where we don't require advanced HTTP features like pooling, connection reuse, or retry strategies.
For rapid prototyping and quick integrations.
Limitations
No connection reuse: a new connection is created for each request.
Cannot tune many HTTP-layer concerns (e.g., keep-alive, socket buffering, etc.).
Not suitable for production-level microservices or distributed systems.
2. Using HttpComponentsClientHttpRequestFactory
Backed by Apache HttpClient, this factory allows advanced HTTP capabilities including:
Connection pooling
Retry policies
Custom headers, interceptors
SSL configuration
Request-level tuning
Characteristics
Supports fine-grained timeout control: connection timeout, read timeout, and connection request timeout.
Integrates well with enterprise-grade HTTP configurations.
Suitable for high-performance and scalable applications.
Supports connection reuse, improving performance.
When to Use
For enterprise-scale applications or microservices communicating over HTTP.
When we need connection pooling for performance optimization.
If we are interacting with external APIs or services with potential for high latency.
Additional Benefits
Can plug in a custom HttpClient with additional configurations (e.g., proxy, TLS versions, keep-alive).
Better control for timeouts per route or host.
3. Using RestTemplateBuilder
A Spring Boot convenience builder for creating RestTemplate instances in a more declarative and chainable manner.
Characteristics
Encourages cleaner, more readable code.
Automatically injects common configurations (e.g., message converters, interceptors).
Easily integrates with application properties, profiles, and dependency injection.
Under the hood, it can use any
ClientHttpRequestFactory, most commonly the Apache one in Spring Boot setups.
When to Use
In Spring Boot applications, where idiomatic configuration and centralization are preferred.
When we want to keep timeout and other settings externalized via config files (YAML/properties).
If we want to create preconfigured RestTemplate beans shared across services with minimal boilerplate.
We can combine it with .requestFactory(...) to fully customize the underlying factory (e.g., inject Apache HttpClient).
Advantages
Aligns well with Spring Boot auto-configuration.
Works seamlessly with
@ConfigurationPropertiesfor dynamic timeout settings.Useful for unit testing, as the builder can be mocked or overridden easily.
Adding Interceptors
Interceptors in RestTemplate allow we to intercept HTTP requests and responses before they are sent and after they are received. This provides a powerful mechanism to:
Enrich or modify the request (e.g., add headers)
Log outgoing and incoming traffic
Propagate context (like trace IDs, auth tokens)
Handle cross-cutting concerns like metrics, retries, or API versioning
They are analogous to servlet filters but applied to outbound HTTP calls.
Interface: ClientHttpRequestInterceptor
ClientHttpRequestInterceptorEach interceptor implements the following interface:
request: Contains metadata like headers and URL.body: Raw request body in bytes.execution: Used to proceed with the actual call.
How to Register Interceptors ?
We can add interceptors to a RestTemplate either programmatically or through RestTemplateBuilder.
Registering Manually
Example
1. Add Standard Headers (e.g., Authentication, Correlation IDs)
This is useful when every service call needs security and traceability.
2. Centralized Logging of Requests/Responses
This is critical in environments where auditing, debugging, or API telemetry is required.
3. Dynamic API Key Injection Based on Service
Used in multi-tenant or multi-provider integrations.
Custom Message Converters
In Spring’s RestTemplate, message converters are responsible for serializing Java objects into HTTP request bodies and deserializing HTTP response bodies into Java objects. These converters implement the interface HttpMessageConverter.
Spring provides a set of default converters (like MappingJackson2HttpMessageConverter for JSON), but we can register our own converters when:
Working with custom media types
Using an alternative serialization library (e.g., Gson, Protobuf)
Customizing how objects are serialized/deserialized (e.g., date formats, field naming, null handling)
Default Converters
Spring Boot pre-configures the following (based on dependencies):
StringHttpMessageConverter
Text/plain
text/plain
MappingJackson2HttpMessageConverter
JSON using Jackson
application/json
Jaxb2RootElementHttpMessageConverter
XML via JAXB
application/xml
FormHttpMessageConverter
Form data
application/x-www-form-urlencoded
These are added to RestTemplate when it’s auto-configured via RestTemplateBuilder.
Why Customize Message Converters ?
Need to support additional serialization formats
Protocol Buffers, Avro, Smile
Require fine-tuned Jackson behavior
Use snake_case, omit nulls, custom serializers
Work with encrypted or compressed payloads
Custom stream-based converter
Our API uses non-standard media types
e.g., application/vnd.company.v1+json
Need to use libraries like Gson or Moshi
Replacing Jackson entirely
How to Add Custom Message Converters ?
Programmatic Registration
Use Case: Supporting a Custom Media Type
Register this converter along with our RestTemplate.
Use Case: Replace Jackson with Gson
How Converters Are Selected
When a request or response is processed:
Spring inspects the
Content-TypeandAcceptheaders.It looks for the first compatible converter that supports both the Java type and media type.
If none match, it throws an
HttpMediaTypeNotSupportedException.
We can manipulate this behavior by adjusting:
AcceptandContent-TypeheadersSupported media types in our converter
Converter order in the list
Connection Pooling
Connection pooling is a technique used to reuse existing HTTP connections instead of opening a new connection for every request. When RestTemplate is used with its default setup (SimpleClientHttpRequestFactory), each request opens a new HTTP connection, which is expensive in high-throughput applications.
To optimize resource usage and improve performance, Spring allows RestTemplate to be configured with connection pooling using a more advanced ClientHttpRequestFactory, typically backed by Apache HttpClient or OkHttp.
Why Connection Pooling Matters ?
Avoid overhead of creating new TCP connections
Reduces latency and CPU usage
Reuses persistent connections
Boosts throughput for HTTP/1.1 keep-alive
Handles concurrent requests efficiently
Suitable for microservices, APIs, batch jobs
Enables timeout management
Controls socket/connect/read timeouts
Provides fine-grained tuning
Max connections, eviction, retries
Default vs. Pooled
Default
SimpleClientHttpRequestFactory
New connection per request
Pooled
HttpComponentsClientHttpRequestFactory (Apache) or OkHttp3ClientHttpRequestFactory
Reuses connections via pool
Apache HttpClient Setup for Pooling
setMaxTotal(100)
Total max connections in the pool
setDefaultMaxPerRoute(20)
Max concurrent connections per route (host)
setConnectTimeout(3000)
Time to establish TCP connection
setSocketTimeout(5000)
Time waiting for data after connection
setConnectionRequestTimeout(2000)
Time waiting to obtain a connection from the pool
evictIdleConnections(...)
Closes idle connections after timeout
Using OkHttp Instead
OkHttpClient supports connection pooling and HTTP/2 by default.
Logging
1. Enable Basic RestTemplate Logging
Logs high-level info: HTTP method, URL, status, etc
Example log:
2. Enable Underlying HTTP Client Logging
a) Default (SimpleClientHttpRequestFactory → java.net.HttpURLConnection)
Enable JDK HTTP wire logging:
Prints headers and some payload info.
Useful if we are not overriding the HTTP client.
b) Apache HttpClient (HttpComponentsClientHttpRequestFactory)
If we use Apache HttpClient under RestTemplate, enable:
org.apache.http→ general client internals.org.apache.http.headers→ logs request & response headers.org.apache.http.wire→ logs raw request & response bodies (wire format).
c) OkHttp (OkHttp3ClientHttpRequestFactory)
If we use OkHttp:
Use
HttpLoggingInterceptorfor detailed body logging (more flexible than logger-only).
3. Enable Message Converter Logging
Spring uses HttpMessageConverters to serialize/deserialize request/response bodies. Enable logging for Jackson (JSON):
Prints details when converting JSON request/response.
4. Enable Client Factory Logging
Shows which HTTP client factory (
SimpleClientHttpRequestFactory,HttpComponentsClientHttpRequestFactory, etc.) RestTemplate is using.
Last updated