Reactor WebClient

У меня есть функция HandlerFunction, которая принимает POST-запрос BookingRecord. Я получаю Mono от ServerRequest с помощью bodyToMono (), а затем подписываюсь на Mono, поскольку мне нужен тип BookingRecord, чтобы вызвать службу REST, чтобы вернуть Mono "" с помощью WebClient. Я объявил тариф как переменную экземпляра, чтобы использовать его в операторе возврата.

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.


person Krishnakumar Ramachandran    schedule 15.10.2018    source источник


Ответы (1)


За кулисами вы уже подписываетесь, ожидая результата, поэтому нет необходимости подписываться снова. Вам нужно рассматривать каждый шаг как строительный блок, поэтому сначала вы получаете запись о бронировании (1), когда она будет завершена, затем создайте URL-адрес с записью (2), затем запросите 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)

;
person Kevin Hussey    schedule 15.10.2018
comment
Клятва. Это было отлично. Я только полностью знакомлюсь с реактором !!. Спасибо. - person Krishnakumar Ramachandran; 15.10.2018