使用 Spring Reactive 时如何验证 Mono
Posted
技术标签:
【中文标题】使用 Spring Reactive 时如何验证 Mono【英文标题】:How to validate Mono when using Spring Reactive 【发布时间】:2018-04-24 23:32:10 【问题描述】:我们正在为一个项目评估 Spring 5,但不确定如何最好地验证 Mono
参数。传统上,我们一直使用 MethodValidationPostProcessor 来验证我们的方法参数,如下所示:
@Validated
@Service
public class FooService
@Validated(SignUpValidation.class)
public void signup(@Valid UserCommand userCommand)
...
然后我们将在ControllerAdvice
或ErrorController
中处理异常,并将合适的 4xx 响应传递给客户端。
但是当我将参数更改为Mono
时,如下所示,它似乎不再起作用了。
@Validated
@Service
public class FooService
@Validated(SignUpValidation.class)
public Mono<Void> signup(@Valid Mono<UserCommand> userCommand)
...
据我了解 Spring Reactive,可能它实际上不应该工作。那么,验证 Mono
s 和 Flux
es,然后发送合适的错误响应的 Spring 5 最佳实践是什么?
【问题讨论】:
【参考方案1】:在回答这个问题之前不要急,您方法的 void
返回类型在反应式应用程序中是非常不寻常的。看这个,似乎这个方法应该异步执行实际工作,但该方法返回一个同步类型。我在回答中将其更改为Mono<Void>
。
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 确实支持验证”)。那是哪里?以上是关于使用 Spring Reactive 时如何验证 Mono的主要内容,如果未能解决你的问题,请参考以下文章
如何将 GlobalMethodSecurityConfiguration 迁移到 Reactive Spring?
如何在 Spring WebFlux Security(Reactive Spring Security)配置中将多个用户角色添加到单个 pathMatcher/Route?
Reactive Spring实战 -- 响应式Kafka交互
Spring WebFlux Reactive 和 Kotlin Coroutines 启动错误
使用 Spring Security OAuth 时 Spring Boot Reactive WebClient “serverWebExchange must be null”