在REST控制器中,我需要调用一个REST来获取一个值,作为第二个REST调用的URI变量。
@PostMapping
public void abbina(@RequestBody DocumentsUploadRequest documentsUploadRequest) {
Mono<GetResult> result = WebClient
.create(url)
.get()
.....
.retrieve()
.bodyToMono(GetResult.class)
;
WebClient.post()
.uri(...)
.path("/{partita}")
.build(result.block().getValue()))
.....
.bodyToMono(PostResult.class)
....
}
问题是,在WebFlux内部,在mono/flux上调用block是不可能的。
代码抛出
. lang。IllegalStateException block()/blockFirst()/blockLast()线程反应器-http
中不支持阻塞
I tried to change
.build (result.block () .getValue ()))
.build (result.share () .block () .getValue ()))
但现在的问题是result.share().block()
无限期挂起。
首先,永远不要在响应式管道中阻塞。您应该订阅代替。在这种特殊情况下,只要你提供发布者,Spring Webflux框架就会为你订阅。要实现这一点,controller方法必须像这样返回Mono
发布者:
@PostMapping
public Mono<Void> abbina(@RequestBody Attribute documentsUploadRequest) {
}
这里,Mono<Void>
定义了你的发布者将不带任何值地完成。
那么你必须构建一个没有阻塞的响应式管道。
第一个HTTP调用的结果是GetResult
的Mono
:
private Mono<GetResult> getResult() {
return WebClient
.get()
//...
.retrieve()
.bodyToMono(GetResult.class);
}
同样,第二个HTTP调用返回PostResult
的Mono
:
private Mono<PostResult> postResult(String firstResult) {
return WebClient
.post()
//...
.retrieve()
.bodyToMono(PostResult.class);
}
最后,结合这两个发布者,以便使用flatmap
操作符构建管道:
@PostMapping
public Mono<Void> abbina(@RequestBody Attribute documentsUploadRequest) {
return getResult()
.flatMap(result -> postResult(result.getValue()))
.then();
}
我建议你看一下下面的指南:构建响应式RESTful Web服务