当前位置: 首页 > 知识库问答 >
问题:

如果Flux stream数据具有错误状态,如何返回不同的ServerResponse

云承弼
2023-03-14

我正在使用WebFlux实现一个RESTendpoint,我在基本操作上没有任何问题,但是有一个操作我不知道如何管理。我想返回与事件对象相关的PriceMessage对象,所以如果事件存在,endpoint返回一个ServerResponse.ok(),但是如果事件不存在,应该返回一个ServerResponse.not发现()。

在存储库层中,如果存在eventId为的代码和事件,则有以下方法返回一个表示代码的Mono,并返回一个Mono。空()如果没有:

@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;
}

然后,服务层返回一个流量,如果未找到事件或连接到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

任何帮助都将不胜感激。

共有2个答案

殷宾白
2023-03-14

您可以在注册路由时使用“选择”来处理它。

@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();
}

或者您可以在服务器上使用用户onErrorResume

return ServerResponse.ok().body(priceService.getPrices(eventId), PriceMessage.class).onErrorResume((e) -> ServerResponse.notFound().build());

希望这有帮助。

姬自强
2023-03-14

如果发生错误,可以使用OneErrorResume创建错误响应。

 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());
 类似资料:
  • 下面是我正在使用的一段代码: 期望reponse conatins的状态行:“HTTP/1.1400坏请求”想知道这是可以实现的吗?如果是,那么我如何继续做同样的事情。

  • 问题内容: 我有一个对快速服务器(我自己的服务器)进行反应的组件。服务器用于在上签署交易。一旦将交易包含在一个块中,就将一个对象返回给服务器。看起来像这样: 我需要将存入上述组件的状态。我已经搜索了2天,可能丢失了一些非常明显的内容。 这是服务器端代码还是客户端代码?由于与之交谈的固有时间延迟,我是否需要学习和使用异步? 任何帮助表示赞赏! 谢谢 问题答案: 要发出发布请求,您必须通过compon

  • 我在Grafana中有一个图形,使用Prometheus数据源显示API中的错误率。这可以很好地处理此查询: 我从我的API中获得非200响应代码的速率,然后将这些速率相加,因为我有3个运行API的实例。然后,我将这些分组为(用户请求的实际路径)和,后者是返回的确切的HTTP状态代码。 虽然这是一个有点有用的原始数字,但没有那么大的帮助。每秒100个请求中有100个错误是非常糟糕的,1000000

  • 当我使用MVC控制器时,我使用“返回OK(对象)”或“返回BadRequest(ErrorMessage)”等。 我怎样才能实现这是剃刀页? 我尝试返回新的JSON result(object);这在状态代码为200时有效。但是如果我想返回带有JSON错误消息的状态代码400呢?

  • 问题内容: 我试图按照此链接中的建议将错误返回到对控制器的调用,以便客户端可以采取适当的措施。javascript通过jqueryAJAX调用控制器。仅在不将状态设置为error的情况下,我才可以重新获得Json对象。这是示例代码 如果没有设置状态码,我会得到Json。如果设置状态代码,则会返回状态代码,但不会返回Json错误对象。 更新 我想将Error对象作为JSON发送,以便可以处理ajax

  • 问题内容: 我正在运行以下MySQL查询,以查找没有手册(且车轮有黑轮等)的汽车 查询的结果看起来正确,但是它两次返回ID为27的汽车。如何更改查询,以使所有结果都是唯一的(没有重复项)? 问题答案: 假定这是唯一的主键,那么其中的一种联接将导致笛卡尔乘积。也就是说:或包含多个匹配项。 子查询通常是消除笛卡尔积的好工具。下面的示例查询显示了两种使用子查询的方法。 第一个子查询可确保我们只查看在20