0

当使用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);
}

WebClient 与.retrieve()

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

WebClient 与.exchangeToMono()

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
});

难道我做错了什么?

4

2 回答 2

2

我不知道你为什么这样做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>.

于 2021-12-21T19:05:07.413 回答
1

响应Mono为空,因为它已被 消耗.exchangeToMono,因此操作符按预期single()失败。NoSuchElementException

于 2021-12-21T16:21:21.613 回答