Synchronous Use

WebClient 可以通过在最后阻塞以获取结果以同步方式使用:

WebClient can be used in synchronous style by blocking at the end for the result:

  • Java

  • Kotlin

Person person = client.get().uri("/person/{id}", i).retrieve()
	.bodyToMono(Person.class)
	.block();

List<Person> persons = client.get().uri("/persons").retrieve()
	.bodyToFlux(Person.class)
	.collectList()
	.block();
val person = runBlocking {
	client.get().uri("/person/{id}", i).retrieve()
			.awaitBody<Person>()
}

val persons = runBlocking {
	client.get().uri("/persons").retrieve()
			.bodyToFlow<Person>()
			.toList()
}

但是,如果需要进行多个调用,则避免对每个响应单独进行阻塞并改为等待组合结果会更有效:

However if multiple calls need to be made, it’s more efficient to avoid blocking on each response individually, and instead wait for the combined result:

  • Java

  • Kotlin

Mono<Person> personMono = client.get().uri("/person/{id}", personId)
		.retrieve().bodyToMono(Person.class);

Mono<List<Hobby>> hobbiesMono = client.get().uri("/person/{id}/hobbies", personId)
		.retrieve().bodyToFlux(Hobby.class).collectList();

Map<String, Object> data = Mono.zip(personMono, hobbiesMono, (person, hobbies) -> {
			Map<String, String> map = new LinkedHashMap<>();
			map.put("person", person);
			map.put("hobbies", hobbies);
			return map;
		})
		.block();
val data = runBlocking {
		val personDeferred = async {
			client.get().uri("/person/{id}", personId)
					.retrieve().awaitBody<Person>()
		}

		val hobbiesDeferred = async {
			client.get().uri("/person/{id}/hobbies", personId)
					.retrieve().bodyToFlow<Hobby>().toList()
		}

		mapOf("person" to personDeferred.await(), "hobbies" to hobbiesDeferred.await())
	}

以上只是一个示例。还有许多其他模式和运算符可以拼凑一个反应性管道,它可以进行许多远程调用,可能是一些嵌套的、相互依赖的,直到最后都不会阻塞。

The above is merely one example. There are lots of other patterns and operators for putting together a reactive pipeline that makes many remote calls, potentially some nested, interdependent, without ever blocking until the end.

使用 FluxMono,您永远不必在 Spring MVC 或 Spring WebFlux 控制器中阻塞。只需从控制器方法返回生成的反应性类型。相同的原理适用于 Kotlin 协程和 Spring WebFlux,只需在控制器方法中使用挂起的函数或返回 Flow 即可。

With Flux or Mono, you should never have to block in a Spring MVC or Spring WebFlux controller. Simply return the resulting reactive type from the controller method. The same principle apply to Kotlin Coroutines and Spring WebFlux, just use suspending function or return Flow in your controller method .