Reactor WebClient

时间:2018-10-15 10:00:22

标签: spring-webflux reactor

我有下面的HandlerFunction,它接受“ BookingRecord”的POST请求。我使用bodyToMono()从ServerRequest中获取一个Mono,然后订阅Mono,因为需要返回BookingRecord类型,以使用WebClient调用REST服务以获取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);

那么为什么我的第一个代码没有调用subscribe? 我正在使用SpringBoot 2.1.0.M4。

1 个答案:

答案 0 :(得分:1)

在幕后,您已经在等待结果,因此无需真正订阅。您需要将每个步骤作为构建块进行查看,因此首先获得预订记录(1),完成后,然后使用记录(2)构建URL,然后请求URL(3),完成后返回响应主体(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)

;