In anticipation of the start of the Spring Framework Developer course , we have prepared a traditional translation of useful material.
We also offer absolutely free of charge to watch a demo-lesson recording on the topic "Introduction to clouds, creating a cluster in Mongo DB Atlas" .
WebClient — , HTTP-.
RestTemplate
NOTE: As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward. Please, consider using the
org.springframework.web.reactive.client.WebClient
which has a more modern API and supports sync, async, and streaming scenarios.
: 5.0, . ,
org.springframework.web.reactive.client.WebClient
, API , .
, , RestTemplate , . , WebClient . .
WebClient RestTemplate
, , RestTemplate (), WebClient ( ).
RestTemplate — HTTP-, API HTTP-, HttpURLConnection
(JDK), HttpComponents
(Apache) .
Spring WebClient — , HTTP-, Spring WebFlux.
, , , . WebClient . WebClient.
RestTemplate , WebClient.
WebClient
-
JDK 11
. — spring-boot-starter-webflux
.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
Spring WebFlux Spring 5 -.
WebClient.
WebClient
WebClient. — .
WebClient client = WebClient.create();
URL:
WebClient client = WebClient.create("http://base-url.com");
— WebClient . , URL .
@Configuration
public class WebClientConfiguration {
private static final String BASE_URL = "https://jsonplaceholder.typicode.com";
public static final int TIMEOUT = 1000;
@Bean
public WebClient webClientWithTimeout() {
final var tcpClient = TcpClient
.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT)
.doOnConnected(connection -> {
connection.addHandlerLast(new ReadTimeoutHandler(TIMEOUT, TimeUnit.MILLISECONDS));
connection.addHandlerLast(new WriteTimeoutHandler(TIMEOUT, TimeUnit.MILLISECONDS));
});
return WebClient.builder()
.baseUrl(BASE_URL)
.clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))
.build();
}
}
Spring WebClient
WebClient : get()
, post()
, put()
, patch()
, delete()
, options()
head()
.
:
(
path variables
)uri()
.
headers()
.
cookies()
.
retrieve()
exchange()
. Mono bodyToMono()
Flux bodyToFlux()
.
, WebClient .
@Service
@AllArgsConstructor
public class UserService {
private final WebClient webClient;
public Mono<User> getUserByIdAsync(final String id) {
return webClient
.get()
.uri(String.join("", "/users/", id))
.retrieve()
.bodyToMono(User.class);
}
}
, User. User Mono-, . , subscribe()
.
userService
.getUserByIdAsync("1")
.subscribe(user -> log.info("Get user async: {}", user));
subscribe()
, .
, block()
.
public User getUserByIdSync(final String id) {
return webClient
.get()
.uri(String.join("", "/users/", id))
.retrieve()
.bodyToMono(User.class)
.block();
}
, . .
, . . retryWhen()
, response.util.retry.Retry
.
public User getUserWithRetry(final String id) {
return webClient
.get()
.uri(String.join("", "/users/", id))
.retrieve()
.bodyToMono(User.class)
.retryWhen(Retry.fixedDelay(3, Duration.ofMillis(100)))
.block();
}
(, ). , repeatWhen()
repeatWhenEmpty()
retryWhen()
.
, , . :
doOnError()
— , Mono .
onErrorResume()
— , .
, , .
public User getUserWithFallback(final String id) {
return webClient
.get()
.uri(String.join("", "/broken-url/", id))
.retrieve()
.bodyToMono(User.class)
.doOnError(error -> log.error("An error has occurred {}", error.getMessage()))
.onErrorResume(error -> Mono.just(new User()))
.block();
}
. onStatus()
.
public User getUserWithErrorHandling(final String id) {
return webClient
.get()
.uri(String.join("", "/broken-url/", id))
.retrieve()
.onStatus(HttpStatus::is4xxClientError,
error -> Mono.error(new RuntimeException("API not found")))
.onStatus(HttpStatus::is5xxServerError,
error -> Mono.error(new RuntimeException("Server is not responding")))
.bodyToMono(User.class)
.block();
}
WebClient .
WebClient.builder()
.baseUrl(BASE_URL)
.filter((request, next) -> next
.exchange(ClientRequest.from(request)
.header("foo", "bar")
.build()))
.clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))
.build();
.
WebClient.builder()
.baseUrl(BASE_URL)
.filter(basicAuthentication("user", "password")) // org.springframework.web.reactive.function.client.basicAuthentication()
.clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))
.build();
, WebClient HTTP-. , , GitHub-. Spring WebClient .
, , WebClient , .
Spring WebClient!
« Spring Framework».
- « , Mongo DB Atlas».