0
# HTTP Clients
1
2
Spring Boot provides auto-configured HTTP client support with RestTemplate and RestClient for making HTTP requests to external services.
3
4
## Capabilities
5
6
### RestTemplate Configuration
7
8
Auto-configured RestTemplate builder for creating HTTP clients.
9
10
```java { .api }
11
/**
12
* RestTemplate builder provided by Spring Boot
13
*/
14
@Autowired
15
private RestTemplateBuilder restTemplateBuilder;
16
17
/**
18
* Create RestTemplate instance
19
*/
20
public RestTemplate restTemplate() {
21
return restTemplateBuilder
22
.rootUri("https://api.example.com")
23
.setConnectTimeout(Duration.ofSeconds(5))
24
.setReadTimeout(Duration.ofSeconds(30))
25
.build();
26
}
27
28
/**
29
* RestTemplate with custom configuration
30
*/
31
@Bean
32
public RestTemplate customRestTemplate() {
33
return new RestTemplateBuilder()
34
.messageConverters(new MappingJackson2HttpMessageConverter())
35
.errorHandler(new CustomResponseErrorHandler())
36
.basicAuthentication("username", "password")
37
.build();
38
}
39
```
40
41
**Usage Examples:**
42
43
```java
44
@Service
45
public class ExternalApiService {
46
47
private final RestTemplate restTemplate;
48
49
public ExternalApiService(RestTemplateBuilder builder) {
50
this.restTemplate = builder
51
.rootUri("https://jsonplaceholder.typicode.com")
52
.setConnectTimeout(Duration.ofSeconds(5))
53
.build();
54
}
55
56
public User getUser(Long id) {
57
return restTemplate.getForObject("/users/{id}", User.class, id);
58
}
59
60
public User createUser(User user) {
61
return restTemplate.postForObject("/users", user, User.class);
62
}
63
64
public void updateUser(Long id, User user) {
65
restTemplate.put("/users/{id}", user, id);
66
}
67
68
public void deleteUser(Long id) {
69
restTemplate.delete("/users/{id}", id);
70
}
71
}
72
```
73
74
### RestTemplate HTTP Methods
75
76
Comprehensive HTTP method support for RESTful operations.
77
78
```java { .api }
79
/**
80
* GET requests
81
*/
82
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables);
83
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables);
84
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables);
85
86
/**
87
* POST requests
88
*/
89
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables);
90
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables);
91
public URI postForLocation(String url, Object request, Object... uriVariables);
92
93
/**
94
* PUT requests
95
*/
96
public void put(String url, Object request, Object... uriVariables);
97
98
/**
99
* DELETE requests
100
*/
101
public void delete(String url, Object... uriVariables);
102
103
/**
104
* Generic exchange method
105
*/
106
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables);
107
public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType);
108
```
109
110
**Usage Examples:**
111
112
```java
113
@Service
114
public class UserApiClient {
115
116
private final RestTemplate restTemplate;
117
118
public UserApiClient(RestTemplateBuilder builder) {
119
this.restTemplate = builder.build();
120
}
121
122
public List<User> getAllUsers() {
123
ResponseEntity<User[]> response = restTemplate.getForEntity(
124
"https://api.example.com/users", User[].class);
125
return Arrays.asList(response.getBody());
126
}
127
128
public User getUserWithHeaders(Long id) {
129
HttpHeaders headers = new HttpHeaders();
130
headers.set("Authorization", "Bearer token");
131
headers.set("Accept", "application/json");
132
133
HttpEntity<String> entity = new HttpEntity<>(headers);
134
135
ResponseEntity<User> response = restTemplate.exchange(
136
"https://api.example.com/users/{id}",
137
HttpMethod.GET,
138
entity,
139
User.class,
140
id
141
);
142
143
return response.getBody();
144
}
145
146
public User createUserWithCustomHeaders(User user) {
147
HttpHeaders headers = new HttpHeaders();
148
headers.setContentType(MediaType.APPLICATION_JSON);
149
headers.set("X-API-Key", "my-api-key");
150
151
HttpEntity<User> requestEntity = new HttpEntity<>(user, headers);
152
153
return restTemplate.postForObject(
154
"https://api.example.com/users",
155
requestEntity,
156
User.class
157
);
158
}
159
}
160
```
161
162
### RestClient (Spring 6.1+)
163
164
Modern HTTP client with fluent API and improved ergonomics.
165
166
```java { .api }
167
/**
168
* RestClient builder provided by Spring Boot
169
*/
170
@Autowired
171
private RestClient.Builder restClientBuilder;
172
173
/**
174
* Create RestClient instance
175
*/
176
public RestClient restClient() {
177
return restClientBuilder
178
.baseUrl("https://api.example.com")
179
.defaultHeader("User-Agent", "MyApp/1.0")
180
.build();
181
}
182
183
/**
184
* RestClient fluent API
185
*/
186
public interface RestClient {
187
RequestHeadersUriSpec<?> get();
188
RequestBodyUriSpec post();
189
RequestBodyUriSpec put();
190
RequestBodyUriSpec patch();
191
RequestHeadersUriSpec<?> delete();
192
RequestBodyUriSpec method(HttpMethod method);
193
}
194
```
195
196
**Usage Examples:**
197
198
```java
199
@Service
200
public class ModernApiClient {
201
202
private final RestClient restClient;
203
204
public ModernApiClient(RestClient.Builder builder) {
205
this.restClient = builder
206
.baseUrl("https://jsonplaceholder.typicode.com")
207
.defaultHeader("Accept", "application/json")
208
.build();
209
}
210
211
public User getUser(Long id) {
212
return restClient.get()
213
.uri("/users/{id}", id)
214
.retrieve()
215
.body(User.class);
216
}
217
218
public List<User> getUsersWithPagination(int page, int size) {
219
return restClient.get()
220
.uri(uriBuilder -> uriBuilder
221
.path("/users")
222
.queryParam("page", page)
223
.queryParam("size", size)
224
.build())
225
.retrieve()
226
.body(new ParameterizedTypeReference<List<User>>() {});
227
}
228
229
public User createUser(User user) {
230
return restClient.post()
231
.uri("/users")
232
.contentType(MediaType.APPLICATION_JSON)
233
.body(user)
234
.retrieve()
235
.body(User.class);
236
}
237
238
public ResponseEntity<User> createUserWithResponseEntity(User user) {
239
return restClient.post()
240
.uri("/users")
241
.body(user)
242
.retrieve()
243
.toEntity(User.class);
244
}
245
246
public void handleErrorResponse(Long id) {
247
try {
248
User user = restClient.get()
249
.uri("/users/{id}", id)
250
.retrieve()
251
.onStatus(HttpStatusCode::is4xxClientError, (request, response) -> {
252
throw new UserNotFoundException("User not found: " + id);
253
})
254
.body(User.class);
255
} catch (UserNotFoundException e) {
256
// Handle specific error
257
}
258
}
259
}
260
```
261
262
### HTTP Message Converters
263
264
Auto-configured message converters for request/response serialization.
265
266
```java { .api }
267
/**
268
* Common HTTP message converters automatically configured
269
*/
270
// Jackson JSON converter
271
MappingJackson2HttpMessageConverter jsonConverter;
272
273
// String converter for text/plain
274
StringHttpMessageConverter stringConverter;
275
276
// Form data converter
277
FormHttpMessageConverter formConverter;
278
279
// Resource converter for file downloads
280
ResourceHttpMessageConverter resourceConverter;
281
282
/**
283
* Custom message converter configuration
284
*/
285
@Configuration
286
public class RestTemplateConfig {
287
288
@Bean
289
public RestTemplate restTemplate() {
290
RestTemplate restTemplate = new RestTemplate();
291
292
List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
293
294
// Add custom JSON converter
295
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
296
jsonConverter.setObjectMapper(customObjectMapper());
297
converters.add(0, jsonConverter);
298
299
return restTemplate;
300
}
301
302
private ObjectMapper customObjectMapper() {
303
return new ObjectMapper()
304
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
305
.registerModule(new JavaTimeModule());
306
}
307
}
308
```
309
310
### Error Handling
311
312
Custom error handling for HTTP client responses.
313
314
```java { .api }
315
/**
316
* Custom response error handler
317
*/
318
public class CustomResponseErrorHandler implements ResponseErrorHandler {
319
320
@Override
321
public boolean hasError(ClientHttpResponse response) throws IOException {
322
return response.getStatusCode().is4xxClientError() ||
323
response.getStatusCode().is5xxServerError();
324
}
325
326
@Override
327
public void handleError(ClientHttpResponse response) throws IOException {
328
HttpStatusCode statusCode = response.getStatusCode();
329
330
if (statusCode.is4xxClientError()) {
331
if (statusCode == HttpStatus.NOT_FOUND) {
332
throw new ResourceNotFoundException("Resource not found");
333
} else if (statusCode == HttpStatus.BAD_REQUEST) {
334
throw new BadRequestException("Invalid request");
335
}
336
} else if (statusCode.is5xxServerError()) {
337
throw new ServiceUnavailableException("Service temporarily unavailable");
338
}
339
}
340
}
341
342
/**
343
* Apply custom error handler
344
*/
345
@Bean
346
public RestTemplate restTemplateWithErrorHandler() {
347
RestTemplate restTemplate = new RestTemplate();
348
restTemplate.setErrorHandler(new CustomResponseErrorHandler());
349
return restTemplate;
350
}
351
```
352
353
### SSL and Authentication
354
355
Configure SSL certificates and authentication for HTTPS endpoints.
356
357
```java { .api }
358
/**
359
* SSL configuration for RestTemplate
360
*/
361
@Bean
362
public RestTemplate secureRestTemplate() throws Exception {
363
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
364
365
SSLContext sslContext = SSLContexts.custom()
366
.loadTrustMaterial(null, acceptingTrustStrategy)
367
.build();
368
369
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
370
371
CloseableHttpClient httpClient = HttpClients.custom()
372
.setSSLSocketFactory(csf)
373
.build();
374
375
HttpComponentsClientHttpRequestFactory requestFactory =
376
new HttpComponentsClientHttpRequestFactory();
377
requestFactory.setHttpClient(httpClient);
378
379
return new RestTemplate(requestFactory);
380
}
381
382
/**
383
* Basic authentication configuration
384
*/
385
@Bean
386
public RestTemplate authenticatedRestTemplate() {
387
return new RestTemplateBuilder()
388
.basicAuthentication("username", "password")
389
.build();
390
}
391
392
/**
393
* OAuth2 client configuration (requires spring-security-oauth2-client)
394
*/
395
@Bean
396
public RestTemplate oauth2RestTemplate(OAuth2AuthorizedClientManager authorizedClientManager) {
397
RestTemplate restTemplate = new RestTemplate();
398
restTemplate.getInterceptors().add(new OAuth2ClientHttpRequestInterceptor(authorizedClientManager));
399
return restTemplate;
400
}
401
```
402
403
## Types
404
405
```java { .api }
406
// RestTemplate for HTTP client operations
407
public class RestTemplate {
408
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables);
409
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables);
410
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables);
411
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables);
412
public void put(String url, Object request, Object... uriVariables);
413
public void delete(String url, Object... uriVariables);
414
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables);
415
}
416
417
// RestTemplate builder for configuration
418
public class RestTemplateBuilder {
419
public RestTemplateBuilder rootUri(String rootUri);
420
public RestTemplateBuilder messageConverters(HttpMessageConverter<?>... messageConverters);
421
public RestTemplateBuilder errorHandler(ResponseErrorHandler errorHandler);
422
public RestTemplateBuilder basicAuthentication(String username, String password);
423
public RestTemplateBuilder setConnectTimeout(Duration connectTimeout);
424
public RestTemplateBuilder setReadTimeout(Duration readTimeout);
425
public RestTemplate build();
426
}
427
428
// Modern RestClient (Spring 6.1+)
429
public interface RestClient {
430
RequestHeadersUriSpec<?> get();
431
RequestBodyUriSpec post();
432
RequestBodyUriSpec put();
433
RequestBodyUriSpec patch();
434
RequestHeadersUriSpec<?> delete();
435
436
interface Builder {
437
Builder baseUrl(String baseUrl);
438
Builder defaultHeader(String header, String... values);
439
Builder defaultHeaders(Consumer<HttpHeaders> headersConsumer);
440
RestClient build();
441
}
442
}
443
444
// HTTP entity for request/response wrapping
445
public class HttpEntity<T> {
446
public HttpEntity();
447
public HttpEntity(T body);
448
public HttpEntity(HttpHeaders headers);
449
public HttpEntity(T body, HttpHeaders headers);
450
451
public HttpHeaders getHeaders();
452
public T getBody();
453
}
454
455
// Response entity with status and headers
456
public class ResponseEntity<T> extends HttpEntity<T> {
457
public HttpStatusCode getStatusCode();
458
public int getStatusCodeValue();
459
460
public static <T> ResponseEntity<T> ok(T body);
461
public static <T> ResponseEntity<T> status(HttpStatusCode status);
462
}
463
464
// HTTP headers utility
465
public class HttpHeaders {
466
public void add(String headerName, String headerValue);
467
public void set(String headerName, String headerValue);
468
public void setContentType(MediaType mediaType);
469
public void setAccept(List<MediaType> acceptableMediaTypes);
470
public void setBearerAuth(String token);
471
public void setBasicAuth(String username, String password);
472
}
473
474
// Parameterized type reference for generic types
475
public abstract class ParameterizedTypeReference<T> {
476
protected ParameterizedTypeReference() {}
477
}
478
```