使用Spring Reactive时如何验证Mono [英] How to validate Mono when using Spring Reactive
问题描述
我们正在评估一个项目的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) {
...
}
然后,我们将在ControllerAdvice
或ErrorController
中处理该异常,并将适当的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的最佳实践是:验证Mono
和Flux
es,然后发送适当的错误响应?
As I understand Spring Reactive, probably it's actually not supposed to work. So, what would be Spring 5 best practices for validating Mono
s and Flux
es, 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屋!