繁体   English   中英

WebFlux - 如何检查 Mono <responseentity<flux<myitem> &gt;&gt; 为空返回 404 </responseentity<flux<myitem>

[英]WebFlux - how to check if Mono<ResponseEntity<Flux<MyItem>>> is empty to return 404

我的代码:

public Mono<ResponseEntity<Flux<TreeItem>>> allGroups(
      @PathVariable(value = "email") String email, ServerWebExchange exchange) {

    return Mono.just(
            userGroupService
                .findGroupByEmail(email) //Flux<GroupById>
                .flatMap(getGroups(email)) //Flux<TreeItem>
                .map(TreeItem::getId) //Flux<UUID>
                .collectList() //Mono<List<UUID>>
                .flatMap(getFilteredGroupIdsForUserPrivilege())
                .flatMapMany(Flux::fromIterable) //Flux<UUID>
                .flatMap(getUserTreeGroups(email)))
        .map(ResponseEntity::ok)
        .defaultIfEmpty(ResponseEntity.notFound().build()); --> is not executed at all when no data are returned

当我传递不存在的 email 时,我的代码返回响应 200,其中包含空数组:[]

在这种情况下,我想返回404 error - 为什么最后一行没有执行?

.defaultIfEmpty(ResponseEntity.notFound().build());

一个方法getUserTreeGroups:

private Function<UUID, Publisher<? extends TreeItem>> getUserTreeGroups(String email) {
    return filteredGroupId -> userGroupService
        .findUserTreeGroup(filteredGroupId, email);
  }

和方法findUserTreeGroup:

public Mono<GroupTreeItem> findUserTreeGroup(UUID groupId, String email) {
    return groupByIdRepo.findById(groupId)
            .flatMap(group -> findChildData(email, group));
  }

我想将 TreeItem 列表返回到前端。 老实说 - 我仍然不明白什么时候使用Mono<ResponseEntity<Flux<TreeItem>>>或者Mono<ResponseEntity<List<TreeItem>>> 有什么不同?

更新应用 Thomas Andolf 的解决方案后:

public Mono<ResponseEntity<Flux<TreeItem>>> userAllTreeGroups(
    @PathVariable(value = "email") String email, ServerWebExchange exchange) {
    return userGroupService
              .findUserGroupByEmail(email) //Flux<GroupById>
              .flatMap(groupById -> userGroupService.findUserTreeGroup(groupById.getId(), email)) //Flux<TreeItem>
              .map(TreeItem::getId) //Flux<UUID>
              .collectList() //Mono<List<UUID>>
              .flatMap(groupIds ->
                  rolePrivilegesService.filterGroupIdsForUserPrivilege(groupIds, GROUP_USER_READ_PRIVILEGE))
              .flatMapMany(Flux::fromIterable) //Flux<UUID>
              .flatMap(filteredGroupId -> userGroupService.findUserTreeGroup(filteredGroupId, email)) //Flux<GroupItem>
              .collectList() //Mono<List<TreeItem>>
              .map(ResponseEntity::ok) //Mono<ResponseEntity<List<TreeItem>>>
              .defaultIfEmpty(ResponseEntity.notFound().build());

但我仍然必须返回 Mono>>。

在您看来,我的方法应该返回什么? Mono>> 喜欢在您的解决方案中???

在我的第二条评论中,我问

为什么将所有内容都放入Mono.just()

而且您没有回答,如果您真的阅读了它,那将解决它,因为这可能导致您的问题。

final List<String> strings = Collections.emptyList();

// You are wrapping a flux in a mono for some strange reason?
final Mono<Flux<String>> wrappedFlux = Mono.just(Flux.fromIterable(strings)
        .flatMap(s -> Mono.just("This never gets run"))
).defaultIfEmpty(Flux.just("This never gets run either, because there is a flux in the mono"));

重写

// Can't test it but something in the lines of the following
return userGroupService
            .findGroupByEmail(email) //Flux<GroupById>
            .flatMap(getGroups(email)) //Flux<TreeItem>
            .map(TreeItem::getId) //Flux<UUID>
            .collectList() //Mono<List<UUID>>
            .flatMap(getFilteredGroupIdsForUserPrivilege())
            .flatMapMany(Flux::fromIterable) //Flux<UUID>
            .flatMap(getUserTreeGroups(email)))
            .collectList()
            .map(ResponseEntity::ok)
            .defaultIfEmpty(ResponseEntity.notFound().build());

Mono<T>将持有一个未来的计算。 当有人订阅它时,它会尝试解析其中的内容,当它的内部状态变为COMPLETED时,它会射出它。

Flux<T>是同样的东西,但适用于许多对象。 你可以想,如果它和以前一样多Mono<T> s,当有人订阅它时,它会尝试解决Flux<T>中每个项目内部的问题,并在状态达到时立即弹出这些问题为每一个人COMPLETED

在您订阅Mono<T> or a Flux` 之前,什么都不会发生。

如果您在订阅时有Mono<Flux<T>> ,它将尝试解析其中的任何内容,而其中的内容是Flux<T> ,因此将直接被射出。

另一方面, Flux<T>没有人订阅,因此其中没有任何内容被解决。 它基本上是死的、空的、没有使用的。

你在问我:

因此,在您看来,在 Mono 中使用 Flux 毫无意义/毫无意义

我刚刚在上面写了反应式编程如何工作的绝对基础知识 您正在从没有人订阅的Mono<T>发出Flux<T>

除非您订阅,否则什么也不会发生。

我建议你从一开始就阅读反应器的文档,这对理解反应式编程的基本概念很有帮助

我不知道您要达到什么目的,因为我没有您的完整代码库,我不知道您要返回什么。

简单来说,您可以像这样编写返回语句

return Mono.just(ResponseEntity.ok(yourService.yourMethod()));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM