【发布时间】:2021-07-24 10:10:55
【问题描述】:
我是 Spring Reactive Web 的新手,遇到了以下问题。我想创建一个带有接受数字 N 的端点的微服务 A,向微服务 B 发送 N 个请求(它为每个请求返回一个字符串),将字符串包装成对象,将它们组合成 List/Flux(?)并返回包含这些对象的 JSON,例如:
{
"number": 4,
"objects": [
{
"name": "first"
},
{
"name": "second"
},
{
"name": "third"
},
{
"name": "fourth"
}
]
}
我想为此使用功能端点。所以我尝试了以下方法(尽我所能简化它):
public class MyObject {
private String name; // here should be a value received from B
// ...
}
public class MyResponse {
private int number;
private Flux<MyObject> objects; // or List?
// ...
}
@Component
@RequiredArgsConstructor
public class MyHandler {
private final MyClient client;
public Mono<ServerResponse> generate(ServerRequest serverRequest) {
return serverRequest.bodyToMono(MyRequestBody.class)
.flatMap(request -> buildServerResponse(HttpStatus.OK, buildResponseBody(request)));
}
private Mono<ServerResponse> buildServerResponse(HttpStatus status, Mono<MyResponse> responseBody) {
return ServerResponse.status(status)
.contentType(MediaType.APPLICATION_JSON)
.body(responseBody, MyResponse.class);
}
private Mono<MyResponse> buildResponseBody(MyRequestBody request) {
return Mono.just(MyResponse.builder()
.number(request.getNumber())
.objects(getObjects(request.getNumber())
.build());
}
private Flux<MyObject> getObjects(int n) {
// how to receive n strings from MyClient, make MyObject from each of them and then combine them together to a Flux/List?
}
public class MyClient {
public Mono<String> getName() {
WebClient client = WebClient.builder().baseUrl(getUrl()).build();
return client.get()
// ...
.retrieve()
.bodyToMono(String.class);
}
private String getUrl() {
// ...
}
}
所以,如果我在 MyResponse 中使用 Flux,我会收到如下响应:
{
"number": 4,
"objects": {
"prefetch": 2147483647,
"scanAvailable": true
}
}
另一方面,如果我尝试使用列表,它似乎在某些时候需要阻塞,并且我收到与它相关的错误。那么,我该怎么做呢?
提前致谢!
更新:如果我使用 collectList().block() 从 Flux 中创建一个列表,我会收到这个:
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread <...>
据我对this 问题的回答了解,当我的方法返回Mono/Flux 时,我永远不应该阻止。将block() 调用提取到一个单独的方法,该方法从返回Mono/Flux 的方法调用并没有帮助。如果我在block() 之前使用share(),那么我的请求将永远执行,出于某种我还不明白的原因。
【问题讨论】:
-
它是一个单声道,包含一个具有属性的对象和其他属性,一个名称为字段名称和值的对象列表,为什么要将其称为通量?
-
@silentsudo 不太了解你 :(
标签: java spring-webflux project-reactor reactive flux