WebClient exchangeToMono 检索空体
WebClient exchangeToMono retrieving empty body
当使用 WebClient 的 exchangeToMono()
时,正文检索部分总是返回一个空的 Mono:
例如,暴露的服务其中returns一个非空的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.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.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
});
我是不是做错了什么?
响应 Mono
为空,因为它已被 .exchangeToMono
使用,因此 single()
运算符按预期失败并返回 NoSuchElementException
。
我不知道你为什么要这样做 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>
.
当使用 WebClient 的 exchangeToMono()
时,正文检索部分总是返回一个空的 Mono:
例如,暴露的服务其中returns一个非空的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.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.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
});
我是不是做错了什么?
响应 Mono
为空,因为它已被 .exchangeToMono
使用,因此 single()
运算符按预期失败并返回 NoSuchElementException
。
我不知道你为什么要这样做 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>
.