使用 Spring Reactive 时如何验证 Mono
How to validate Mono when using Spring Reactive
我们正在评估项目的 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 反应性,可能它实际上不应该工作。那么,验证 Mono
s 和 Flux
es,然后发送合适的错误响应的 Spring 5 个最佳实践是什么?
在回答这个问题之前请尽快,您方法的 void
return 类型在反应式应用程序中非常不寻常。看看这个,似乎这个方法应该异步执行实际工作,但方法 returns 是同步类型。我在我的回答中将其更改为 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();
}
我们正在评估项目的 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 反应性,可能它实际上不应该工作。那么,验证 Mono
s 和 Flux
es,然后发送合适的错误响应的 Spring 5 个最佳实践是什么?
在回答这个问题之前请尽快,您方法的 void
return 类型在反应式应用程序中非常不寻常。看看这个,似乎这个方法应该异步执行实际工作,但方法 returns 是同步类型。我在我的回答中将其更改为 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();
}