在Spring Web Controller

时间:2016-05-12 07:57:54

标签: spring-mvc asynchronous reactor

我目前正在尝试了解Reactor并重构了一个返回Optional<CompanyDetails>的服务方法,而不是使用Reactor的Mono<CompanyDetails>

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,这是否可能,或者我是否完全走错了路线?

1 个答案:

答案 0 :(得分:2)

我自己找到了答案:首先,事实证明Reactor的Mono有一个toCompletableFuture - 方法,而Spring MVC也可以使用它而不是DeferredResult。失败CompletableFuture会像预期的那样抛出异常。

要失败,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();
}

现在好多了。