Adr*_*enW 1 reactive-programming project-reactor spring-webflux
基本上我想要实现的是调用第二个存储库(a ReactiveCrudRepository)或抛出异常,具体取决于调用第一个存储库的结果。
我最初的想法是这样的:
/** Reactive with blocking code */
public Flux<SecondThing> getThings(String firstThingName) {
FirstThing firstThing = firstRepo
.findByName(firstThingName)
// Warning: "Inappropriate blocking method call"
.blockOptional() // this fails in test-context
.orElseThrow(() -> new FirstThingNotFound(firstThingName));
return secondRepo.findAllByFirstThingId(firstThing.getId());
}
Run Code Online (Sandbox Code Playgroud)
这对应于以下非反应式方法:
/** Non-reactive */
public List<SecondThing> getThings(String firstThingName) {
FirstThing firstThing = firstRepo
.findByName(firstThingName)
.orElseThrow(() -> new FirstThingNotFound(firstThingName));
return secondRepo.findAllByFirstThingId(firstThing.getId());
}
Run Code Online (Sandbox Code Playgroud)
我还没有找到一种方法以反应式非阻塞方式做到这一点。Mono我所需要的只是在第一次调用中出现空值时抛出错误,如果不为空则继续管道;但我在这里似乎无法正确使用onErrorStop或doOnError正确使用,并且map没有帮助,因为它跳过了空的Mono.
如果我使用id而不是,我有一个解决方法name,但我对它不太满意,因为它在 是 的实例FirstThing但没有SecondThing链接到它的情况下显示出不同的行为:
/** Reactive workaround 1 */
public Flux<SecondThing> getThings(Long firstThingId) {
return secondRepo
.findAllByFirstThingId(firstThingId)
.switchIfEmpty(
Flux.error(() -> new FirstThingNotFound(firstThingName))
);
}
Run Code Online (Sandbox Code Playgroud)
我发现的另一个解决方法如下,它将空值替换Mono为null值,但它看起来不正确并且也会引发警告:
/** Reactive workaround 2 */
public Flux<SecondThing> getThings(String firstThingName) {
return firstRepo
.findByName(firstThingName)
// Warning: "Passing 'null' argument to parameter annotated as @NotNull"
.defaultIfEmpty(null)
.flatMapMany(
firstThing -> secondRepo.findAllByFirstThingId(firstThing.getId()
)
.onErrorMap(
NullPointerException.class, e -> new FirstThingNotFound(firstThingName)
);
}
Run Code Online (Sandbox Code Playgroud)
将调用链接到两个存储库以便存在或不存在对第二个存储库FirstThing的调用的请求条件的正确方法是什么?firstThingName
我找到了一个如此简单的解决方案,我可能会为没有早点找到它而感到羞愧:
public Flux<SecondThing> getThings(String firstThingName) {
return firstRepo
.findByName(firstThingName)
.switchIfEmpty(Mono.error(() -> new FirstThingNotFound(firstThingName)))
.flatMapMany(
firstThing -> secondRepo.findAllByFirstThingId(firstThing.getId()
);
}
Run Code Online (Sandbox Code Playgroud)
诀窍在于,它switchIfEmpty不会强迫您选择“有效”的替换值,因此可以使用 aMono.error直接传播正确的异常。
| 归档时间: |
|
| 查看次数: |
2120 次 |
| 最近记录: |