【问题标题】:Spring reactive reading web client responseSpring响应式读取Web客户端响应
【发布时间】:2021-08-24 00:45:53
【问题描述】:

我正在学习 Spring Reactive 并且有以下基本的响应式演示代码。

import org.springframework.web.reactive.function.client.WebClient;
// other imports etc

@Slf4j
class WebClientTests {
  private static String baseUrl = "http://localhost:8080";
  private static WebClient client = WebClient.create(baseUrl);
  @Test
  void testWebClient() {
    Instant start = Instant.now();
    Flux.just(1,2,3)
      .map(i -> client.get().uri("/person/{id}", i).retrieve().bodyToFlux(Person.class))
      .subscribe(s -> {
        log.info("subscribed: {}", s);
      });
    log.info("Elapsed time: " + Duration.between(start, Instant.now()).toMillis() + "ms");
  }
}

它输出以下内容。

20:32:55.251 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
20:32:55.652 [main] INFO com.example.reactive.reactivedemo.WebClientTests - subscribed: MonoFlatMap
20:32:55.652 [main] INFO com.example.reactive.reactivedemo.WebClientTests - subscribed: MonoFlatMap
20:32:55.652 [main] INFO com.example.reactive.reactivedemo.WebClientTests - subscribed: MonoFlatMap
20:32:55.668 [main] INFO com.example.reactive.reactivedemo.WebClientTests - Elapsed time: 84ms

但是我不确定为什么它不输出 get 请求的值?它实际上并没有触发端点。

【问题讨论】:

  • 我猜是因为你没有对结果做任何事情,所以也许它被优化了。

标签: spring spring-webflux reactive spring-webclient


【解决方案1】:

您几乎肯定想在您的.map(i -> client.get().uri... 行上使用flatMap(),而不是map()。

map() 用于同步转换,您将返回要映射到的实际值。你没有返回一个实际值——你从你的 map 方法中返回了一个发布者,所以这个发布者只是按原样返回——它永远不会被订阅,因为在你订阅之前什么都没有发生,你的网络请求永远不会执行。

flatMap() 用于非阻塞转换,您返回一个 publisher,它发出一个或多个要映射到的值。该发布者作为您的反应链的一部分被订阅,并且该发布者发出的值沿链传递给下一个操作员。

【讨论】:

  • 感谢您的回答。我认为您在这里找到了一些东西,但它仍然没有触发请求?
  • @Robbo_UK 测试可能在您触发请求之前完成,因为您正在订阅但没有等待请​​求完成。如果你真的想像这样运行测试,那么你应该使用blockLast() 而不是subscribe()。
猜你喜欢
  • 2012-06-30
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
  • 2017-04-23
  • 2018-04-22
相关资源
最近更新 更多