如何在使用Spring Reactive时验证Mono

时间:2017-11-12 02:09:31

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

我们正在评估Spring 5的项目,并不确定如何最好地验证guard let uid = Auth.auth().currentUser?.uid else { return } Database.database().reference().child("images_" + uid + "_links/CoverPhotos").observeSingleEvent(of: .value, with: { (snapshot) in for rest in snapshot.children.allObjects as! [DataSnapshot] { //do stuff } }) 参数。传统上我们一直使用 MethodValidationPostProcessor 来验证我们的方法参数,如下所示:

Mono

然后我们会在@Validated @Service public class FooService @Validated(SignUpValidation.class) public void signup(@Valid UserCommand userCommand) { ... } ControllerAdvice中处理异常,并将合适的4xx响应传递给客户端。

但是当我将参数更改为ErrorController时,如下所示,它似乎无法正常工作。

Mono

据我了解Spring Reactive,可能它实际上不应该工作。那么,用于验证@Validated @Service public class FooService @Validated(SignUpValidation.class) public Mono<Void> signup(@Valid Mono<UserCommand> userCommand) { ... } Mono es,然后发送合适的错误响应的Spring 5最佳做法是什么?

1 个答案:

答案 0 :(得分:3)

快速回答这个问题之前,你的方法的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();
}