【问题标题】:How to validate Mono when using Spring Reactive使用 Spring Reactive 时如何验证 Mono
【发布时间】:2018-04-24 23:32:10
【问题描述】:

我们正在为一个项目评估 Spring 5,但不确定如何最好地验证 Mono 参数。传统上,我们一直使用 MethodValidationPostProcessor 来验证我们的方法参数,如下所示:

@Validated
@Service
public class FooService

@Validated(SignUpValidation.class)
public void signup(@Valid UserCommand userCommand) {

    ...
}

然后我们将在ControllerAdviceErrorController 中处理异常,并将合适的 4xx 响应传递给客户端。

但是当我将参数更改为Mono时,如下所示,它似乎不再起作用了。

@Validated
@Service
public class FooService

@Validated(SignUpValidation.class)
public Mono<Void> signup(@Valid Mono<UserCommand> userCommand) {

    ...
}

据我了解 Spring Reactive,可能它实际上不应该工作。那么,验证 Monos 和 Fluxes,然后发送合适的错误响应的 Spring 5 最佳实践是什么?

【问题讨论】:

    标签: spring spring-mvc spring-boot spring-webflux spring-validator


    【解决方案1】:

    在回答这个问题之前不要急,您方法的 void 返回类型在反应式应用程序中是非常不寻常的。看这个,似乎这个方法应该异步执行实际工作,但该方法返回一个同步类型。我在回答中将其更改为Mono&lt;Void&gt;

    As stated in the reference documentation,Spring WebFlux 确实支持验证。

    但最佳实践在这里有所不同,因为方法参数可以是反应类型。如果方法参数尚未解析,则无法获得验证结果。

    所以这样的事情不会真正起作用:

    // can't have the BindingResult synchronously,
    // as the userCommand hasn't been resolved yet
    public Mono<Void> signup(@Valid Mono<UserCommand> userCommand, BindingResult result)
    
    // while technically feasible, you'd have to resolve 
    // the userCommand first and then look at the validation result
    public Mono<Void> signup(@Valid Mono<UserCommand> userCommand, Mono<BindingResult> result)
    

    反应式操作符更惯用且更易于使用:

    public Mono<Void> signup(@Valid Mono<UserCommand> userCommand) {
        /*
         * a WebExchangeBindException will flow through the pipeline
         * in case of validation error.
         * you can use onErrorResume or other onError* operators
         * to map the given exception to a custom one
         */
        return userCommand.onErrorResume(t -> Mono.error(...)).then();
    }
    

    【讨论】:

    • 谢谢!将我的问题编辑为 Mono。我看到 @Valid 在控制器中工作,但是验证组,例如@Validated(SignUpValidation.class),不工作。此外,使用MethodValidationPostProcessor 验证服务方法(参见我上面的示例)也不起作用。顺便说一句,我找不到您提到的参考文档(您写了“如参考文档中所述,Spring WebFlux 确实支持验证”)。那是哪里?
    • 我认为 WebFlux 不支持验证组;这可能值得在官方问题跟踪器(jira.spring.io)上提出。参考文档中的相关部分仅提及验证输入参数,请参阅docs.spring.io/spring-framework/docs/current/…
    • 刚刚检查过 - 控制器支持验证组,但 MethodValidationPostProcessor 不支持(有一张票:jira.spring.io/browse/SPR-16234)。
    猜你喜欢
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 2017-01-17
    • 2019-10-27
    • 1970-01-01
    • 2020-12-28
    相关资源
    最近更新 更多