java - 如何在 WebFlux 控制器中订阅
问题描述
在 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 在单声道/通量上不可能调用块。
代码抛出
java.lang.IllegalStateException block()/blockFirst()/blockLast() 是阻塞的,线程reactor-http中不支持
我试图改变
.build(result.block().getValue()))
和
.build(result.share().block().getValue()))
但现在问题是result.share().block()
无限期挂起。
解决方案
首先,您永远不应该在反应式管道中阻塞。您应该订阅。在这种特殊情况下,只要您提供发布者,Spring Webflux 框架就会为您订阅。为此,控制器方法必须Mono
像这样返回您的发布者:
@PostMapping
public Mono<Void> abbina(@RequestBody Attribute documentsUploadRequest) {
}
在这里,Mono<Void>
您的发布者将完成的定义没有任何价值。
然后你必须建立一个没有阻塞的反应管道。
第一次 HTTP 调用的结果Mono
是GetResult
:
private Mono<GetResult> getResult() {
return WebClient
.get()
//...
.retrieve()
.bodyToMono(GetResult.class);
}
同样,第二个 HTTP 调用返回 a 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();
}
我建议查看以下指南:构建反应式 RESTful Web 服务
推荐阅读
- node.js - 需要使用 fastify-multer 将图像上传到 AWS S3 服务器得到 [Function: multerPreHandler] 错误
- matlab - 如何在 MATLAB 代码中与 GD 收敛?显然在矩阵维度上显示错误
- python - opencv 在转换为 CIELUV 和 CIELAB 时给出的像素范围与标准不同
- javascript - 当 props 改变时渲染组件,否则不显示
- javascript - 在 react.js 中使用 promise 获取数据。状态为空。为什么?
- javascript - 通过单击元素打开 icCube 仪表板(带参数)
- vue.js - 为什么这个 Vue3 转换会破坏数据绑定?
- object - Delphi Sydney Object Inspector 意外消隐
- node.js - 将 Blob 数据从 MySql DB 转换到谷歌云存储时出错
- c# - 如何在 C# 中调用参数类型的参数构造函数?