【问题标题】:Getting 404 error when returning Mono Void返回 Mono Void 时出现 404 错误
【发布时间】:2020-07-17 21:33:35
【问题描述】:

我正在使用 Spring Web Flux 创建一个用于学习目的的 Web 应用程序,我有一个函数,它首先检查记录是否存在,然后更新它,否则它会抛出自定义 NotFoundException。问题是当我返回 Mono 时,控制器会抛出 404 错误,但是当我返回更新的类对象时,它运行良好,我不想返回整个对象。

以下代码运行良好

public Mono<Application> publish(String id,boolean publish) 
{
    return appRepository.findById(id).flatMap( a -> {
        a.setPublished(publish);
        return appRepository.save(a);
    }).switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")));
}

及以下发生404错误的代码

public Mono<Void> publish(String id,boolean publish) 
{
    return appRepository.findById(id).flatMap( a -> {
        a.setPublished(publish);
        appRepository.save(a);
        return Mono.empty().then();
    }).switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")));
}

我已经从 ReactiveMongoRepository 扩展了存储库,控制器类只是调用服务函数

@PutMapping(APP_ROOT_URL + "/{id}/publish")
public Mono<Void>  publish(@PathVariable("id") String id)
{
    return appService.publish(id, true);
}

【问题讨论】:

  • 请添加语言和平台作为标签。
  • @Haider 希望我的回答能消除你的疑惑。
  • @AbhinabaChakraborty 是的,非常感谢。

标签: java spring-webflux


【解决方案1】:

第一个方法没有返回 404 因为:

appRepository.save(a) 返回持久化的实体。不是空的单声道。所以不会触发 switchIfEmpty 子句。

这是来自 ReactiveCrudRepository 的文档(ReactiveMongoRepository 的父存储库之一)

   /**
     * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
     * entity instance completely.
     *
     * @param entity must not be {@literal null}.
     * @return {@link Mono} emitting the saved entity.
     * @throws IllegalArgumentException in case the given {@literal entity} is {@literal null}.
     */
    <S extends T> Mono<S> save(S entity);

在第二种方法中,您显式返回空单声道。这就是触发 switchIfEmpty 子句的原因。

还有一件事,我想指出: switchIfEmpty 子句放置不正确。由于findById 在没有找到记录的 id 时返回一个空单声道,switchIfEmpty 应该在此之后。如果您将switchIfEmpty 放在save 之后,它将永远不会返回空单声道。

所以你应该有这样的东西:

public Mono<Application> publish(String id,boolean publish) 
{
    return appRepository.findById(id)
      .switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")))
      .flatMap( a -> {
        a.setPublished(publish);
        return appRepository.save(a);
    });
}

如果您希望方法的返回类型为Mono&lt;Void&gt;,那么只需使用以下内容:

public Mono<Void> publish(String id, boolean publish) 
{
    return appRepository.findById(id)
      .switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")))
      .flatMap( a -> {
        a.setPublished(publish);
        return appRepository.save(a);
    })
    .then();
}

【讨论】:

    猜你喜欢
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    相关资源
    最近更新 更多