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