0
# Reactive HTTP Client
1
2
The WebClient provides a non-blocking, reactive HTTP client with a fluent API for making HTTP requests. It supports comprehensive request customization, response handling, and error management with full reactive streams integration.
3
4
## Capabilities
5
6
### WebClient Interface
7
8
Main reactive HTTP client interface providing HTTP method builders and configuration options.
9
10
```java { .api }
11
interface WebClient {
12
// HTTP method builders
13
RequestHeadersUriSpec<?> get();
14
RequestHeadersUriSpec<?> head();
15
RequestBodyUriSpec post();
16
RequestBodyUriSpec put();
17
RequestBodyUriSpec patch();
18
RequestHeadersUriSpec<?> delete();
19
RequestHeadersUriSpec<?> options();
20
RequestBodyUriSpec method(HttpMethod method);
21
22
// Configuration
23
Builder mutate();
24
25
// Factory methods
26
static WebClient create();
27
static WebClient create(String baseUrl);
28
static Builder builder();
29
}
30
```
31
32
**Usage Examples:**
33
34
```java
35
// Create WebClient
36
WebClient client = WebClient.create("https://api.example.com");
37
38
// Simple GET request
39
Mono<String> response = client.get()
40
.uri("/users/{id}", 123)
41
.retrieve()
42
.bodyToMono(String.class);
43
44
// POST request with body
45
Mono<User> created = client.post()
46
.uri("/users")
47
.bodyValue(new User("Alice", "alice@example.com"))
48
.retrieve()
49
.bodyToMono(User.class);
50
```
51
52
### WebClient Builder
53
54
Mutable builder for creating and configuring WebClient instances with custom settings.
55
56
```java { .api }
57
interface Builder {
58
Builder baseUrl(String baseUrl);
59
Builder defaultUriVariables(Map<String, ?> defaultUriVariables);
60
Builder uriBuilderFactory(UriBuilderFactory uriBuilderFactory);
61
Builder defaultHeader(String header, String... values);
62
Builder defaultHeaders(Consumer<HttpHeaders> headersConsumer);
63
Builder defaultCookie(String cookie, String... values);
64
Builder defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
65
Builder defaultRequest(Consumer<RequestHeadersSpec<?>> defaultRequest);
66
Builder defaultStatusHandler(Predicate<HttpStatusCode> statusPredicate,
67
Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction);
68
Builder filter(ExchangeFilterFunction filter);
69
Builder filters(Consumer<List<ExchangeFilterFunction>> filtersConsumer);
70
Builder clientConnector(ClientHttpConnector connector);
71
Builder codecs(Consumer<ClientCodecConfigurer> configurer);
72
Builder exchangeStrategies(ExchangeStrategies strategies);
73
Builder exchangeFunction(ExchangeFunction exchangeFunction);
74
Builder observationRegistry(ObservationRegistry observationRegistry);
75
Builder observationConvention(ClientRequestObservationConvention observationConvention);
76
Builder apply(Consumer<Builder> builderConsumer);
77
Builder clone();
78
WebClient build();
79
}
80
```
81
82
**Usage Examples:**
83
84
```java
85
WebClient client = WebClient.builder()
86
.baseUrl("https://api.example.com")
87
.defaultHeader("Authorization", "Bearer " + token)
88
.defaultHeader("Content-Type", "application/json")
89
.filter(ExchangeFilterFunction.ofRequestProcessor(
90
request -> {
91
System.out.println("Request: " + request.url());
92
return Mono.just(request);
93
}))
94
.build();
95
```
96
97
### Request Specification
98
99
URI specification interface for building request URIs with variables and functions.
100
101
```java { .api }
102
interface UriSpec<S extends RequestHeadersSpec<S>> {
103
S uri(URI uri);
104
S uri(String uri, Object... uriVariables);
105
S uri(String uri, Map<String, ?> uriVariables);
106
S uri(String uri, Function<UriBuilder, URI> uriFunction);
107
S uri(Function<UriBuilder, URI> uriFunction);
108
}
109
```
110
111
**Usage Examples:**
112
113
```java
114
// URI with path variables
115
client.get().uri("/users/{id}/posts/{postId}", 123, 456)
116
117
// URI with map variables
118
Map<String, Object> vars = Map.of("userId", 123, "postId", 456);
119
client.get().uri("/users/{userId}/posts/{postId}", vars)
120
121
// URI with builder function
122
client.get().uri(uriBuilder ->
123
uriBuilder.path("/search")
124
.queryParam("q", "spring")
125
.queryParam("page", 1)
126
.build())
127
```
128
129
### Request Headers Specification
130
131
Interface for specifying request headers and executing requests.
132
133
```java { .api }
134
interface RequestHeadersSpec<S extends RequestHeadersSpec<S>> {
135
S accept(MediaType... acceptableMediaTypes);
136
S acceptCharset(Charset... acceptableCharsets);
137
S cookie(String name, String value);
138
S cookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
139
S ifModifiedSince(ZonedDateTime ifModifiedSince);
140
S ifNoneMatch(String... ifNoneMatches);
141
S header(String headerName, String... headerValues);
142
S headers(Consumer<HttpHeaders> headersConsumer);
143
S attribute(String name, Object value);
144
S attributes(Consumer<Map<String, Object>> attributesConsumer);
145
S httpRequest(Consumer<ClientHttpRequest> requestConsumer);
146
147
// Response handling
148
ResponseSpec retrieve();
149
<V> Mono<V> exchangeToMono(Function<ClientResponse, ? extends Mono<V>> responseHandler);
150
<V> Flux<V> exchangeToFlux(Function<ClientResponse, ? extends Flux<V>> responseHandler);
151
@Deprecated
152
Mono<ClientResponse> exchange();
153
}
154
```
155
156
**Usage Examples:**
157
158
```java
159
client.get()
160
.uri("/api/data")
161
.accept(MediaType.APPLICATION_JSON)
162
.header("X-API-Key", apiKey)
163
.cookies(cookies -> cookies.add("session", sessionId))
164
.retrieve()
165
.bodyToMono(DataResponse.class);
166
```
167
168
### Request Body Specification
169
170
Interface for specifying request body content for POST, PUT, PATCH requests.
171
172
```java { .api }
173
interface RequestBodySpec extends RequestHeadersSpec<RequestBodySpec> {
174
RequestBodySpec contentLength(long contentLength);
175
RequestBodySpec contentType(MediaType contentType);
176
RequestHeadersSpec<?> bodyValue(Object body);
177
<T> RequestHeadersSpec<?> bodyValue(T body, ParameterizedTypeReference<T> bodyType);
178
<T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, Class<T> elementClass);
179
<T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, ParameterizedTypeReference<T> elementTypeRef);
180
RequestHeadersSpec<?> body(Object producer, Class<?> elementClass);
181
RequestHeadersSpec<?> body(Object producer, ParameterizedTypeReference<?> elementTypeRef);
182
RequestHeadersSpec<?> body(BodyInserter<?, ? super ClientHttpRequest> inserter);
183
}
184
```
185
186
**Usage Examples:**
187
188
```java
189
// Simple body value
190
client.post()
191
.uri("/users")
192
.contentType(MediaType.APPLICATION_JSON)
193
.bodyValue(new User("Alice", "alice@example.com"))
194
.retrieve()
195
.bodyToMono(User.class);
196
197
// Publisher body
198
Flux<User> userStream = Flux.just(user1, user2, user3);
199
client.post()
200
.uri("/users/batch")
201
.body(userStream, User.class)
202
.retrieve()
203
.bodyToMono(BatchResult.class);
204
```
205
206
### Response Specification
207
208
Interface for handling HTTP responses with error handling and body extraction.
209
210
```java { .api }
211
interface ResponseSpec {
212
ResponseSpec onStatus(Predicate<HttpStatusCode> statusPredicate,
213
Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction);
214
ResponseSpec onRawStatus(IntPredicate statusCodePredicate,
215
Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction);
216
217
// Body extraction
218
<T> Mono<T> bodyToMono(Class<T> elementClass);
219
<T> Mono<T> bodyToMono(ParameterizedTypeReference<T> elementTypeRef);
220
<T> Flux<T> bodyToFlux(Class<T> elementClass);
221
<T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> elementTypeRef);
222
223
// Entity extraction
224
<T> Mono<ResponseEntity<T>> toEntity(Class<T> bodyClass);
225
<T> Mono<ResponseEntity<T>> toEntity(ParameterizedTypeReference<T> bodyTypeReference);
226
<T> Mono<ResponseEntity<List<T>>> toEntityList(Class<T> elementClass);
227
<T> Mono<ResponseEntity<List<T>>> toEntityList(ParameterizedTypeReference<T> elementTypeRef);
228
<T> Mono<ResponseEntity<Flux<T>>> toEntityFlux(Class<T> elementType);
229
<T> Mono<ResponseEntity<Flux<T>>> toEntityFlux(ParameterizedTypeReference<T> elementTypeReference);
230
<T> Mono<ResponseEntity<Flux<T>>> toEntityFlux(BodyExtractor<Flux<T>, ? super ClientHttpResponse> bodyExtractor);
231
Mono<ResponseEntity<Void>> toBodilessEntity();
232
}
233
```
234
235
**Usage Examples:**
236
237
```java
238
// Error handling
239
Mono<User> user = client.get()
240
.uri("/users/{id}", 123)
241
.retrieve()
242
.onStatus(HttpStatusCode::is4xxClientError,
243
response -> Mono.error(new UserNotFoundException()))
244
.onStatus(HttpStatusCode::is5xxServerError,
245
response -> Mono.error(new ServiceUnavailableException()))
246
.bodyToMono(User.class);
247
248
// Get full response entity
249
Mono<ResponseEntity<User>> entity = client.get()
250
.uri("/users/{id}", 123)
251
.retrieve()
252
.toEntity(User.class);
253
```
254
255
### Client Request and Response
256
257
Immutable representations of HTTP requests and responses in WebClient.
258
259
```java { .api }
260
interface ClientRequest {
261
HttpMethod method();
262
URI url();
263
HttpHeaders headers();
264
MultiValueMap<String, String> cookies();
265
BodyInserter<?, ? super ClientHttpRequest> body();
266
Map<String, Object> attributes();
267
268
// Constants
269
String LOG_ID_ATTRIBUTE = "LOG_ID_ATTRIBUTE";
270
}
271
272
interface ClientResponse {
273
HttpStatusCode statusCode();
274
Headers headers();
275
MultiValueMap<String, ResponseCookie> cookies();
276
ExchangeStrategies strategies();
277
HttpRequest request();
278
279
// Body extraction
280
<T> T body(BodyExtractor<T, ? super ClientHttpResponse> extractor);
281
<T> Mono<T> bodyToMono(Class<? extends T> elementClass);
282
<T> Mono<T> bodyToMono(ParameterizedTypeReference<T> elementTypeRef);
283
<T> Flux<T> bodyToFlux(Class<? extends T> elementClass);
284
<T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> elementTypeRef);
285
Mono<Void> releaseBody();
286
287
// Entity conversion
288
<T> Mono<ResponseEntity<T>> toEntity(Class<T> bodyClass);
289
<T> Mono<ResponseEntity<T>> toEntity(ParameterizedTypeReference<T> bodyTypeReference);
290
}
291
```
292
293
### Exchange Strategies and Filters
294
295
Configuration for HTTP message readers/writers and request/response filtering.
296
297
```java { .api }
298
interface ExchangeStrategies {
299
List<HttpMessageReader<?>> messageReaders();
300
List<HttpMessageWriter<?>> messageWriters();
301
Builder mutate();
302
303
static ExchangeStrategies withDefaults();
304
static Builder builder();
305
static Builder empty();
306
}
307
308
@FunctionalInterface
309
interface ExchangeFilterFunction {
310
Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next);
311
}
312
313
@FunctionalInterface
314
interface ExchangeFunction {
315
Mono<ClientResponse> exchange(ClientRequest request);
316
}
317
```
318
319
**Usage Examples:**
320
321
```java
322
// Custom exchange filter
323
ExchangeFilterFunction logFilter = ExchangeFilterFunction.ofRequestProcessor(
324
request -> {
325
logger.info("Request: {} {}", request.method(), request.url());
326
return Mono.just(request);
327
});
328
329
WebClient client = WebClient.builder()
330
.filter(logFilter)
331
.build();
332
```
333
334
### Exception Classes
335
336
WebClient-specific exceptions for error handling.
337
338
```java { .api }
339
class WebClientException extends RuntimeException {
340
// Base exception for WebClient operations
341
}
342
343
class WebClientRequestException extends WebClientException {
344
// Exception for request-related errors
345
HttpMethod getMethod();
346
URI getUri();
347
}
348
349
class WebClientResponseException extends WebClientException {
350
// Exception for response-related errors with status code information
351
HttpStatusCode getStatusCode();
352
String getStatusText();
353
HttpHeaders getHeaders();
354
byte[] getResponseBodyAsByteArray();
355
String getResponseBodyAsString();
356
}
357
358
class UnknownHttpStatusCodeException extends WebClientResponseException {
359
// Exception for unknown HTTP status codes
360
int getRawStatusCode();
361
}
362
```
363
364
### Support Classes
365
366
Additional classes for WebClient integration and decoration.
367
368
```java { .api }
369
class WebClientAdapter {
370
// Adapter for integrating WebClient with other HTTP client abstractions
371
}
372
373
class ClientResponseWrapper implements ClientResponse {
374
// Wrapper for ClientResponse to enable decoration patterns
375
protected ClientResponseWrapper(ClientResponse delegate);
376
ClientResponse getDelegate();
377
}
378
```