反应式 Spring WebClient 调用

Posted

技术标签:

【中文标题】反应式 Spring WebClient 调用【英文标题】:Reactive Spring WebClient calls 【发布时间】:2020-04-29 16:21:29 【问题描述】:

我正在尝试了解 WebFlux,但在使用 Webclient 调用时遇到了一些问题。我没有看到 这一行 System.out.println("customerId = " + customerId);执行它似乎没有调用端点。 但是如果我使用 .subscribe(customer -> ); 订阅 webclient然后我可以看到这一行 System.out.println("customerId = " + customerId);作品 在端点侧。我不明白为什么我必须订阅 Mono 通话,还是必须订阅?谢谢

@GetMapping("/customer/customerId")
@ResponseStatus(HttpStatus.ACCEPTED)
public Mono<Void> getCustomer(@PathVariable("customerId") int customerId) 
     WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build();

 webClient.get()
  .uri("/client/customer/customerId",customerId)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(Customer.class);//here do I have to subscribe to actually activate to call?

 return null;



@GET
@Path("/customer/customerId")
@Produces(MediaType.APPLICATION_JSON)
public Customer getCustomer(@PathParam("customerId") int customerId) throws InterruptedException 
    System.out.println("customerId = " + customerId);  // I do not see the call comes thru if I dont subscribe to flux call.
    return new Customer(customerId,"custName");
 

【问题讨论】:

是的,您必须订阅。这是响应式编程的一个基本原则:订阅是一切的触发因素。在您订阅之前什么都不会发生。 projectreactor.io/docs/core/release/reference/… 但是为什么你从一个应该返回 Mono 的方法中返回 null 呢?为什么 getCustomer 方法会返回 Mono?它不应该得到客户吗?如果你真的想返回一个 Mono,那么你就不会订阅。 Spring 将为您订阅您返回的 Mono。 JB 尼泽,你是对的。返回 Void 是没有意义的。这只是一个不太关心返回类型的示例。不过感谢您的指出。 如果你通过webclient返回结果Mono,那么你不需要显式订阅。 【参考方案1】:

如果您想从 WebClient 返回响应式类型,则必须从控制器方法中返回它,例如:

@GetMapping("/customer/customerId")
@ResponseStatus(HttpStatus.ACCEPTED)
public Mono<Customer> getCustomer(@PathVariable("customerId") int customerId) 
     WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build();

 return webClient.get()
  .uri("/client/customer/customerId",customerId)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(Customer.class);

您还可以从端点返回 Customer 并阻止并等待 WebClient 的结果,然后离开反应式生态系统,例如:

@GetMapping("/customer/customerId")
@ResponseStatus(HttpStatus.ACCEPTED)
public Customer getCustomer(@PathVariable("customerId") int customerId) 
     WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build();

 return webClient.get()
  .uri("/client/customer/customerId",customerId)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(Customer.class)
  .block()

如果您正在查看 Spring 的 WebClient 的一般介绍,请查看 this tutorial

【讨论】:

以上是关于反应式 Spring WebClient 调用的主要内容,如果未能解决你的问题,请参考以下文章

Spring WebClient 使用简介

Spring WebClient 使用简介

Spring WebClient 使用简介

Spring Webflux webclient 出现问题,尝试发送发布请求时没有任何反应

如何使用 WebClient 使用响应式 Spring Rest API

如何在 Spring 响应式 WebClient 中返回 Kotlin Coroutines Flow