Mastering Spring Boot RestClient: Build Synchronous HTTP Clients Efficiently
This guide explains how to create and configure Spring Boot's RestClient, covering instance creation, request building, header and body handling, response retrieval, error processing, the exchange method, and available client request factories for robust synchronous HTTP communication.
Environment: SpringBoot 3.2.1
1. Introduction
RestClient is a synchronous HTTP client that offers a fluent API, abstracting underlying HTTP libraries and enabling easy conversion between Java objects and HTTP requests/responses.
2. Creating a RestClient instance
RestClient is created via the static create() method or a builder that allows selecting the HTTP library, message converters, base URL, default URI variables, headers, interceptors, etc. The resulting client is thread‑safe.
<code>// Simple create
RestClient defaultClient = RestClient.create();
// Builder example
RestClient customClient = RestClient.builder()
.requestFactory(new HttpComponentsClientHttpRequestFactory())
.messageConverters(converters -> converters.add(new PackCustomMessageConverter()))
.baseUrl("http://api.pack.com")
.defaultUriVariables(Map.of("name", "zs"))
.defaultHeader("My-Header", "Foo")
.requestInterceptor(...)
.requestInitializer(...)
.build();
</code>3. Using RestClient
3.1 Request URI
Specify the request URI with uri() . If a default base URL is configured, this step can be omitted. URLs are encoded by default but can be customized via a custom uriBuilderFactory .
<code>RestClient restClient = RestClient.create("http://api.pack.com");
restClient.method(HttpMethod.GET).uri("/users");
</code>3.2 Request Headers and Body
Add headers with header() or convenience methods such as accept() , contentType() , etc. Set the request body with body(Object) or with a ParameterizedTypeReference for generic types. A callback can write directly to an OutputStream .
<code>RestClient restClient = RestClient.create("http://api.pack.com");
restClient.post()
.uri("/users")
.body(new User(666L, "张三", 23))
.header("X-API-VERSION", "1.0");
</code>3.3 Retrieving the response
Call retrieve() and then body(Class) or body(ParameterizedTypeReference) to convert the response body. The response can also be obtained as a ResponseEntity to access status and headers.
<code>RestClient restClient = RestClient.create("http://api.pack.com");
User user = restClient.get()
.uri("/users/666")
.retrieve()
.body(User.class);
</code> <code>ResponseEntity<String> result = RestClient.create("http://api.pack.com")
.get()
.uri("/users/666")
.accept(APPLICATION_JSON)
.retrieve()
.toEntity(User.class);
System.out.println("Response status: " + result.getStatusCode());
System.out.println("Response headers: " + result.getHeaders());
System.out.println("Contents: " + result.getBody());
</code>3.4 Error handling
By default, 4xx/5xx responses throw a RestClientException . Use onStatus to provide custom handling.
<code>String result = restClient.get()
.uri("/users/{id}", id)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError,
(request, response) -> {
throw new MyCustomRuntimeException(response.getStatusCode(),
response.getHeaders());
})
.body(String.class);
</code>3.5 Exchange
The exchange method gives full access to the underlying request and response, bypassing the default status handling.
<code>RestClient restClient = RestClient.create("http://api.pack.com");
restClient.post()
.uri("/users/666")
.body(new User())
.header("X-API-VERSION", "1.0")
.exchange((request, response) -> {
if (response.getStatusCode().is4xxClientError()) {
throw new RuntimeException(String.format("status: %d, headers: %s",
response.getStatusCode(), response.getHeaders()));
} else {
return response.getBody();
}
});
</code>3.6 Client request factories
RestClient delegates HTTP execution to a ClientRequestFactory . Available implementations include JdkClientHttpRequestFactory , HttpComponentsClientHttpRequestFactory , JettyClientHttpRequestFactory , ReactorNettyClientRequestFactory , and SimpleClientHttpRequestFactory . If none is specified, RestClient picks an implementation based on the classpath (Apache/Jetty) or Java’s HttpClient when the java.net.http module is present.
End of article.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.