我正在使用WebFlux实现REST端点,并且在基本操作上没有任何问题,但是有一个我不知道如何管理的操作。 我想返回与事件对象相关的PriceMessage对象,因此,如果事件存在,则端点返回ServerResponse.ok(),但如果事件不存在,则应返回ServerResponse.notFound()。
在存储库层中,有以下方法,如果存在且带有eventId的事件,则返回表示代码的Mono,如果不存在,则返回Mono.empty():
@Override
public Mono<Integer> getSportsEventId(long eventId) {
Optional<SourceEventDto> optionalSourceEvent =
springJpaSourceEventRepository.findByEventId(eventId);
Mono<Integer> result = Mono.empty();
if (optionalSourceEvent.isPresent()) {
result = Mono.just(new Integer(optionalSourceEvent.get().getSourceId()));
}
return result;
}
然后,服务层将返回一个Flux,如果未找到事件,则该Flux将设置错误,或者连接到Redis以获取与sportsEventId相关的价格:
@Override
public Flux<PriceMessage> getPrices(long eventId) {
return
// get the sportsEventId
sourceEventRepository.getSportsEventId(eventId)
// notify the event does not exist
.switchIfEmpty(Mono.error(new IllegalStateException("Event " + eventId + " does not exist")))
// get the related PriceEntity objects
.flatMapMany(priceRepository::findBySporsEventId)
// transform to PriceMessage
.map(priceMessageFactory::from);
}
此代码已经过单元测试,并且还调试了它,以确保如果在流中设置了错误,则不会调用flatMapMany和map部件。
最后,在REST层中有以下代码,即快乐的路径:
public Mono<ServerResponse> getPricesByEventId(ServerRequest request) {
String eventIdParam = request.pathVariable("eventId");
// call the service layer
Flux<PriceMessage> prices = priceService.getPrices(eventId);
return
ServerResponse.ok()
.contentType(MediaType.APPLICATION_STREAM_JSON)
.body(prices, PriceMessage.class);
}
这很好,但如果价格流包含错误,因为找不到事件,我不知道如何返回404错误,在主体中设置错误消息,如下所示:
ServerResponse.status(HttpStatus.NOT_FOUND)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.syncBody(<error_message_from_flux>);
伪代码将是这样,但我无法将其转换为反应性:
if (!prices.isError()) then
return
ServerResponse.ok()
.contentType(MediaType.APPLICATION_STREAM_JSON)
.body(prices, PriceMessage.class);
else
return
ServerResponse.status(HttpStatus.NOT_FOUND)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.syncBody(<error_message_from_flux>);
end
任何帮助将不胜感激。
答案 0 :(得分:2)
如果发生错误,可以使用onErrorResume创建错误响应。
return priceService.getPrices(eventId).flatMap(prices -> ServerResponse.ok()
.contentType(MediaType.APPLICATION_STREAM_JSON)
.body(prices, PriceMessage.class))
.onErrorResume(err -> ServerResponse.status(HttpStatus.NOT_FOUND).body({Your Error Body Here}).build());
答案 1 :(得分:0)
您可以在注册路线时使用选择来处理它。
@Bean
public RouterFunction<ServerResponse> route(PriceMessageHandler handler) {
return RouterFunctions.route().GET("/",
request -> ServerResponse.ok().body(handler.handle(request), PriceMessage.class))
.onError(Exception.class, (e, a) -> ServerResponse.status(HttpStatus.NOT_FOUND).build())
.build();
}
或者您可以在ServerResponse上使用onErrorResume
:
return ServerResponse.ok().body(priceService.getPrices(eventId), PriceMessage.class).onErrorResume((e) -> ServerResponse.notFound().build());
希望这会有所帮助。