【问题标题】:Consuming a Mono<T> in a Spring web Controller在 Spring Web 控制器中使用 Mono<T>
【发布时间】:2016-05-12 07:57:54
【问题描述】:

我目前正在尝试了解 Reactor,并重构了一个返回 Optional&lt;CompanyDetails&gt; 的服务方法,以改用 Reactor 的 Mono&lt;CompanyDetails&gt;

public Mono<CompanyDetails> findOne(String id) {
    CompanyDetails result = retrieveFromSomewhere(id);
    return Mono.justOrEmpty(result);
}

据我了解,这应该发出 empty()just(result)。 我像这样在 Spring Web Controller 中使用该服务:

@RequestMapping(value = "{id}", method = RequestMethod.GET)
public DeferredResult<CompanyDetails> getCompany(@PathVariable String id) {
    final DeferredResult<CompanyDetails> result = new DeferredResult<>();
    companyService.findOne(id)
            .consume(result::setResult);
    return result;
}

如果找到结果,这会正常工作,但如果 findOne 发出 empty() 它会超时。我可以显式调用get() 并检查null,但这感觉完全错误。

另外:在重构之前,getCompany 抛出了 NotFoundException 如果没有找到结果,这有可能吗,还是我完全走错了轨道?

【问题讨论】:

    标签: spring-mvc asynchronous reactor


    【解决方案1】:

    自己找到了答案:首先发现 Reactor 的 Mono 有一个 toCompletableFuture 方法,Spring MVC 也可以使用它来代替 DeferredResultCompletableFuture 失败会按预期抛出异常。

    要失败,Mono 必须发出 error 而不是 empty

    public Mono<CompanyDetails> findOne(String id) {
        CompanyDetails result = retrieveFromSomewhere(id);
        return Mono
                .justOrEmpty(result)
                .otherwiseIfEmpty(Mono.error(...));
    }
    
    @RequestMapping(value = "{id}", method = RequestMethod.GET)
    public CompletableFuture<CompanyDetails> getCompany(@PathVariable String id) {
        return companyService.findOne(id)
                .toCompletableFuture();
    }
    

    现在好多了。

    【讨论】:

      猜你喜欢
      • 2021-11-03
      • 1970-01-01
      • 2018-08-23
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2019-03-26
      • 1970-01-01
      相关资源
      最近更新 更多