Reactor 网络客户端

Reactor WebClient

我有下面的 HandlerFunction,它接受 "BookingRecord" 的 POST 请求。我使用 bodyToMono() 从 ServerRequest 获取 Mono,然后订阅 Mono,因为我需要返回 BookingRecord 类型,调用 REST 服务以使用 WebClient 取回 Mono""。我已将 fare 声明为实例变量,以便我可以在 return 语句中使用它。

public class BookingHandler
{
   private Mono<Fare>           fare;
   private WebClient            webClient= = WebClient.create("http://localhost:8080");

   public HandlerFunction<ServerResponse> book = request -> {

    request.bodyToMono(BookingRecord.class)
            .subscribe(br ->
            {
                fare = this.webClient.get()
                        .uri("/fares/get/{flightNumber}/{flightDate}", br.getFlightNumber(), br
                                .getFlightDate())
                        .retrieve()
                        .bodyToMono(Fare.class);
            });
    return ServerResponse.ok()
            .body(BodyInserters.fromPublisher(fare, Fare.class));
};
}

但是这段代码不起作用。订阅似乎没有执行!!这是为什么?

我必须将其更改为以下代码才能正常工作!。

 request.bodyToMono(BookingRecord.class)
                        .subscribe(br ->
                    {
                    flightNumber = br.getFlightNumber();
                    flightDate = br.getFlightDate();
                });

        fare = this.webClient.get()
                .uri("/fares/get/{flightNumber}/{flightDate}", flightNumber, flightDate)
                .retrieve()
                .bodyToMono(Fare.class);

那么为什么我的第一个代码没有调用订阅? 我使用的是 SpringBoot 2.1.0.M4.

在幕后,您已经通过等待结果进行订阅,因此无需再次订阅。您需要将每个步骤视为一个构建块,因此首先获取预订记录(1),当此完成后,然后使用记录(2)构建一个url,然后请求URL( 3)、当这完成时return响应体(4)。您需要将这些中的每一个构建到一个流程 (5) 中。 您的第二个示例之所以有效,是因为您很幸运订阅在您构建 url 之前完成,或者因为它是在另一个执行中填充的。

public HandlerFunction<ServerResponse> book = request -> request.bodyToMono(BookingRecord.class) //(1)
                .map(br -> this.webClient.get()
                        .uri("/fares/get/{flightNumber}/{flightDate}", br.getFlightNumber(), br
                                .getFlightDate()) //(2)
                        .retrieve() (3)
                        .bodyToMono(Fare.class) (4)
                ).flatMap(fare -> ServerResponse.ok().body(BodyInserters.fromPublisher(fare, Fare.class))) (5)

;