如何在 WebFlux 控制器中订阅
How to subscribe inside a WebFlux Controller
在 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 REST 内部不可能在 mono/flux 上调用块。
代码抛出
java.lang.IllegalStateException block()/blockFirst()/blockLast() are
blocking, which is not supported in thread reactor-http
我试着改变
.build(result.block().getValue()))
和
.build(result.share().block().getValue()))
但现在的问题是 result.share().block()
无限期挂起。
首先,你不应该在反应管道中阻塞。您应该 订阅 。在这种情况下,只要您提供发布者,Spring Webflux 框架就会为您订阅。为此,控制器方法必须像这样 return 你的 Mono
发布者:
@PostMapping
public Mono<Void> abbina(@RequestBody Attribute documentsUploadRequest) {
}
此处,Mono<Void>
定义您的发布商将完成而没有任何价值。
然后你必须构建一个无阻塞的反应管道。
第一个 HTTP 调用的结果是 Mono
of GetResult
:
private Mono<GetResult> getResult() {
return WebClient
.get()
//...
.retrieve()
.bodyToMono(GetResult.class);
}
同样,第二个 HTTP 调用 return 是 Mono
of PostResult
:
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();
}
我建议您查看以下指南:Building a Reactive RESTful Web Service
在 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 REST 内部不可能在 mono/flux 上调用块。
代码抛出
java.lang.IllegalStateException block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http
我试着改变
.build(result.block().getValue()))
和
.build(result.share().block().getValue()))
但现在的问题是 result.share().block()
无限期挂起。
首先,你不应该在反应管道中阻塞。您应该 订阅 。在这种情况下,只要您提供发布者,Spring Webflux 框架就会为您订阅。为此,控制器方法必须像这样 return 你的 Mono
发布者:
@PostMapping
public Mono<Void> abbina(@RequestBody Attribute documentsUploadRequest) {
}
此处,Mono<Void>
定义您的发布商将完成而没有任何价值。
然后你必须构建一个无阻塞的反应管道。
第一个 HTTP 调用的结果是 Mono
of GetResult
:
private Mono<GetResult> getResult() {
return WebClient
.get()
//...
.retrieve()
.bodyToMono(GetResult.class);
}
同样,第二个 HTTP 调用 return 是 Mono
of PostResult
:
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();
}
我建议您查看以下指南:Building a Reactive RESTful Web Service