使用Spring Reactor的Mono与多个switchIfEmpty

huangapple go评论91阅读模式
英文:

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(&quot;Its not valid&quot;);
}

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 -&gt; !req.isValid())
        .switchIfEmpty(Mono.error(new ValidationException(&quot;Its not valid&quot;)))
        .filter(req -&gt; !req.isCorrect())
        .switchIfEmpty(Mono.error(new IncorrectException()))
        .flatMap(req -&gt; 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 -&gt; !req.isValid())
            .switchIfEmpty(Mono.defer(() -&gt; Mono.error(new ValidationException(&quot;Its not valid&quot;))))
            .filter(req -&gt; !req.isCorrect())
            .switchIfEmpty(Mono.defer(() -&gt; Mono.error(new IncorrectException())))
            .flatMap(req -&gt; 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 -&gt; req.isValid()) 
    // if it was invalid, its empty, thus switches to error:
    .switchIfEmpty(Mono.error(new ValidationException(&quot;Its not valid&quot;))) 
    // filters out which is not correct:
    .filter(req -&gt; req.isCorrect())
    // if not correct, its empty, switch to error:
    .switchIfEmpty(Mono.error(new IncorrectException())) 
    .flatMap(req -&gt; Mono.just(someService.process(req)));

huangapple
  • 本文由 发表于 2020年8月17日 19:55:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63450285.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定