【问题标题】:Mono<Optional<Object>> with switchIfEmpty带有 switchIfEmpty 的 Mono<Optional<Object>>
【发布时间】:2020-08-22 17:39:05
【问题描述】:

使用下面的实现,如果Mono&lt;Optional&lt;Item&gt;&gt; 为空,它会转到switchIfEmpty,但不能按预期工作。

public Mono<ServerResponse> getItemById(ServerRequest request) {
        JwtClaim claim = retrieveClaimFromRequest(request);
        String itemId = request.pathVariable("itemId");
        Mono<ServerResponse> notFound = ServerResponse.notFound().build();
        Mono<Optional<Item>> item = Mono.just(itemRepository.findById(Long.parseLong(itemId)));
        return item
                .flatMap(retItem -> ServerResponse.ok().contentType(APPLICATION_JSON).bodyValue(retItem))
                .switchIfEmpty(notFound);
    }

【问题讨论】:

  • 您确定要使用Mono&lt;Optional&lt;Object&gt;&gt;吗? bodyValue 将设置为Optional&lt;Item&gt;,而不是Item。还有你使用flatMap而不是map的具体原因吗?
  • 另外,Mono 属于哪个框架?我猜是反应堆?
  • @Turing85,你是对的,它给出了 Optional。最好的处理方法是什么?
  • Mono&lt;Item&gt; item = Mono.just(itemRepository.findById(Long.parseLong(itemId)).orElse(null)); 可以修复它,但不是空安全的。如果您希望 findById 返回某些内容,您可能希望通过调用 orElseThrow(...) 来引发适用的异常。
  • 如果 NotFound 为空,我想返回它。

标签: spring java-8 optional spring-webflux project-reactor


【解决方案1】:

您当前解决方案的问题是Optional&lt;Item&gt;总是返回并可用,无论是实际内容还是空内容,但实例本身存在在那里。

最好的方法是使用Mono.justOrEmpty(Optional),它将Optional 作为参数并创建一个空的Mono 或带有内容的Mono

Mono<Item> item = Mono.justOrEmpty(itemRepository.findById(Long.parseLong(itemId)));

return item.flatMap(retItem -> ServerResponse.ok().build())
           .switchIfEmpty(ServerResponse.notFound().build());

实际上,它与您使用Optional::orElse 的结果对Mono&lt;Mono&lt;Item&gt;&gt; 进行平面映射一样:

Mono<Optional<Item>> item = Mono.just(itemRepository.findById(Long.parseLong(itemId)));
    
return item.flatMap(opt -> opt.map(Mono::just).orElse(Mono.empty()))
           ...

【讨论】:

    猜你喜欢
    • 2020-12-06
    • 2021-11-28
    • 2020-05-09
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    相关资源
    最近更新 更多