英文:
Using Spring Reactor Mono with multiple switchIfEmpty
问题
我之前有一个简单的Java验证流程,就像这个例子一样:
```java
if (!request.isValid()) {
throw new ValidationException("Its not valid");
}
if (!request.isCorrect()) {
throw new IncorrectException();
}
return Mono.just(
someService.process(request)
);
我尝试通过链式方法调用来消除if
语句,但是这样并不起作用:
return Mono.just(request)
.filter(req -> !req.isValid())
.switchIfEmpty(Mono.error(new ValidationException("Its not valid")))
.filter(req -> !req.isCorrect())
.switchIfEmpty(Mono.error(new IncorrectException()))
.flatMap(req -> Mono.just(someService.process(req)));
问题在于,即使在isValid()
上失败,代码也会继续执行,并且第二个switch
会覆盖第一个。
我该如何使代码正常工作并保留链式调用?
<details>
<summary>英文:</summary>
I had a simple java validation flow like this example:
```java
if (!request.isValid()) {
throw new ValidationException("Its not valid");
}
if (!request.isCorrect()) {
throw new IncorrectException();
}
return Mono.just(
someService.process(request)
);
I tried to chain method calls to get rid of ifs
but this does not work:
return Mono.just(request)
.filter(req -> !req.isValid())
.switchIfEmpty(Mono.error(new ValidationException("Its not valid")))
.filter(req -> !req.isCorrect())
.switchIfEmpty(Mono.error(new IncorrectException()))
.flatMap(req -> Mono.just(someService.process(req)));
The problem is, even if it fails on isValid()
the code goes on and the second switch
overwrites the first one.
How could I make the code working and retain the chaining?
答案1
得分: 3
你尝试过使用"Mono.defer()"吗?
你的代码应该像这样:
return Mono.just(request)
.filter(req -> !req.isValid())
.switchIfEmpty(Mono.defer(() -> Mono.error(new ValidationException("它无效")))
.filter(req -> !req.isCorrect())
.switchIfEmpty(Mono.defer(() -> Mono.error(new IncorrectException())))
.flatMap(req -> Mono.just(someService.process(req)));
我之前也遇到过相同的问题,这个方法对我起了作用。
你可以在这个帖子中了解更多关于Mono.defer()的信息:
https://stackoverflow.com/questions/55955567/what-does-mono-defer-do
英文:
Have you tried to use "Mono.defer()"?
Your code would be something like:
return Mono.just(request)
.filter(req -> !req.isValid())
.switchIfEmpty(Mono.defer(() -> Mono.error(new ValidationException("Its not valid"))))
.filter(req -> !req.isCorrect())
.switchIfEmpty(Mono.defer(() -> Mono.error(new IncorrectException())))
.flatMap(req -> Mono.just(someService.process(req)));
I had the same issue, and it worked for me.
You can read more about Mono.defer() on this thread:
https://stackoverflow.com/questions/55955567/what-does-mono-defer-do
答案2
得分: 1
因为筛选条件应该相反,所以它不起作用。您指定了什么可以通过,而不是被过滤掉的内容:
return Mono.just(request)
// 仅允许有效的请求通过:
.filter(req -> req.isValid())
// 如果无效,它为空,因此切换到错误状态:
.switchIfEmpty(Mono.error(new ValidationException("不是有效的请求")))
// 过滤掉不正确的请求:
.filter(req -> req.isCorrect())
// 如果不正确,它为空,切换到错误状态:
.switchIfEmpty(Mono.error(new IncorrectException()))
.flatMap(req -> Mono.just(someService.process(req)));
请注意,上面的代码注释已经翻译成了中文,只有代码部分保持原样。
英文:
It is not working because the filters should be the opposite. You specify what passes, not what filtered out:
return Mono.just(request)
// lets through valid request only:
.filter(req -> req.isValid())
// if it was invalid, its empty, thus switches to error:
.switchIfEmpty(Mono.error(new ValidationException("Its not valid")))
// filters out which is not correct:
.filter(req -> req.isCorrect())
// if not correct, its empty, switch to error:
.switchIfEmpty(Mono.error(new IncorrectException()))
.flatMap(req -> Mono.just(someService.process(req)));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论