简体   繁体   English

Reactor WebClient

[英]Reactor WebClient

I have the below HandlerFunction that takes a POST request of a "BookingRecord". 我有下面的HandlerFunction,它接受“ BookingRecord”的POST请求。 I get a Mono from ServerRequest using bodyToMono(), and then subscribe to the Mono, as I need the BookingRecord type back, to call a REST service to get back a Mono"", using WebClient. 我使用bodyToMono()从ServerRequest中获取一个Mono,然后订阅Mono,因为需要返回BookingRecord类型,以使用WebClient调用REST服务以获取Mono“”。 I have declared fare as an instance variable so that I can use it in return statement. 我已将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));
};
}

But this code doesn't work. 但是此代码不起作用。 The subscribe doesn't seem to execute!! 订阅似乎没有执行! Why is that? 这是为什么?

I had to change it to below code for it to work!. 我必须将其更改为以下代码才能正常工作!

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

So why my first code is not calling subscribe? 那么,为什么我的第一个代码没有调用subscribe? I am using SpringBoot 2.1.0.M4. 我正在使用SpringBoot 2.1.0.M4。

Behind the scenes, you are already subscribing by waiting on the result, so no real need to subscribe again. 在幕后,您已经在等待结果,因此无需真正订阅。 You need to view each step as a building block, so first you get the booking record (1), when this is completed, then build a url with the record (2), then request URL (3), when this is completed return the response body (4). 您需要将每个步骤作为构建块进行查看,因此首先获得预订记录(1),完成后,然后使用记录(2)构建URL,然后请求URL(3),完成后返回响应主体(4)。 You need to build each of these into one flow (5). 您需要将所有这些构建到一个流中(5)。 Your second example worked because you either got lucky that the subscribe finished before you built the url, or because it was populated in another execution. 第二个示例之所以有用,是因为您很幸运在构建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)

;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM