使用Spring Reactive时如何验证Mono [英] How to validate Mono when using Spring Reactive

查看:281
本文介绍了使用Spring Reactive时如何验证Mono的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We are evaluating Spring 5 for a project, and not sure how best to validate Mono parameters. Traditionally we had been using MethodValidationPostProcessor to validate our method parameters as below:

@Validated
@Service
public class FooService

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

    ...
}

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

We would then handle the exception in a ControllerAdvice or ErrorController, and pass a suitable 4xx response to the client.

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

But when I change the parameter to Mono, as below, it no more seems to work.

@Validated
@Service
public class FooService

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

    ...
}

据我了解,Spring Reactive可能实际上不起作用.那么,Spring 5的最佳实践是:验证MonoFlux es,然后发送适当的错误响应?

As I understand Spring Reactive, probably it's actually not supposed to work. So, what would be Spring 5 best practices for validating Monos and Fluxes, and then sending a suitable error response?

推荐答案

在回答这个问题之前,还很迅速,方法的void返回类型在反应式应用程序中是很不常见的.以此看来,该方法似乎应该异步执行实际工作,但该方法返回一个同步类型.我已将其更改为答案中的Mono<Void>.

Quick not before answering that question, the void return type of your method is quite unusual in a reactive application. Looking at this, it seems this method should perform actual work asynchronously but the method returns a synchronous type. I've changed that as a Mono<Void> in my answer.

如参考文档中所述所述,Spring WebFlux确实支持验证.

As stated in the reference documentation, Spring WebFlux does support validation.

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

But best practices differ here, because method parameters can be reactive types. You can't have the validation result if the method parameter hasn't been resolved yet.

所以类似的东西实际上是行不通的:

So something like that won't really work:

// 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)

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

Something more idiomatic and easier to use with reactive operators:

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();
}

这篇关于使用Spring Reactive时如何验证Mono的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆