在 Spring 网络控制器中使用 Mono<T>
Consuming a Mono<T> in a Spring web Controller
我目前正在尝试了解 Reactor 并重构了一个返回 Optional<CompanyDetails>
的服务方法以使用 Reactor 的 Mono<CompanyDetails>
代替:
public Mono<CompanyDetails> findOne(String id) {
CompanyDetails result = retrieveFromSomewhere(id);
return Mono.justOrEmpty(result);
}
根据我的理解,这应该发出 empty()
或 just(result)
。
我在这样的 Spring 网络控制器中使用服务:
@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
,这是否可能,或者我完全走错了路?
自己找到了答案:首先发现 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();
}
现在好多了。
我目前正在尝试了解 Reactor 并重构了一个返回 Optional<CompanyDetails>
的服务方法以使用 Reactor 的 Mono<CompanyDetails>
代替:
public Mono<CompanyDetails> findOne(String id) {
CompanyDetails result = retrieveFromSomewhere(id);
return Mono.justOrEmpty(result);
}
根据我的理解,这应该发出 empty()
或 just(result)
。
我在这样的 Spring 网络控制器中使用服务:
@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
,这是否可能,或者我完全走错了路?
自己找到了答案:首先发现 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();
}
现在好多了。