WebClient exchangeToMono正在检索空正文



使用WebClientexchangeToMono()时,正文检索部分总是返回一个空的Mono:

例如,暴露的服务返回一个非空的Mono

@PostMapping("/test")
public Mono<Pojo> getCalled(@RequestBody Pojo pojo) {
System.out.println(pojo); // always prints a non-null object
return Mono.just(pojo);
}

.retrieve()的WebClient

WebClient.create().post().uri(theUrl).bodyValue(p).retrieve().toEntity(Pojo.class).map(response -> {
if (response.getStatusCode().isError()) {
// do something;
}
return response.getBody();
}).single(); // always get a single element and does not fail

.exchangeToMono()的WebClient

WebClient.create().post().uri(theUrl).bodyValue(p).exchangeToMono(Mono::just).flatMap(response -> {
if (response.statusCode().isError()) {
// do something;
}
return response.bodyToMono(Pojo.class).single(); // fails with java.util.NoSuchElementException: Source was empty
});

我做错什么了吗?

我不知道你为什么要做exchangeToMono(Mono::just).flatMap(response -> ...),因为它毫无意义。

不,您不需要使用Mono两次,您需要阅读有关如何正确使用交换功能的文档WebClient>Exchange

以下是文档中的示例

Mono<Person> entityMono = client.get()
.uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
return response.bodyToMono(Person.class);
}
else {
// Turn to error
return response.createException().flatMap(Mono::error);
}
});

这是你的代码,但在exchangeToMono中做事情,而不是

WebClient.create().post().uri(theUrl).bodyValue(p).exchangeToMono(response -> {
if (response.statusCode().isError()) {
// do something;
}
return response.bodyToMono(Pojo.class).single();
});

exchangeToMono有一个目的,它不只是把东西放进Mono<T>,它在那里是因为你需要使用response,这样服务器就可以释放已经分配的连接。您可以在exchangeToMono中进行检查等操作,然后将身体提取到Mono<T>中。

响应Mono为空,因为它已经被.exchangeToMono消耗,因此single()运算符按预期使用NoSuchElementException失败。

最新更新