我有下面的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。
答案 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)
;