Spring 5 Webflux 功能端点 - 如何执行输入验证?

Spring 5 Webflux functional endpoints - How to perform input validation?

根据当前文档 (5.0.0.RELEASE) Spring Webflux 在使用带注释的控制器时支持验证:

By default if Bean Validation is present on the classpath — e.g. Hibernate Validator, the LocalValidatorFactoryBean is registered as a global Validator for use with @Valid and Validated on @Controller method arguments.

然而,没有提及如何使用功能端点使其自动化。事实上,文档中唯一的输入处理示例并没有验证任何内容:

public Mono<ServerResponse> createPerson(ServerRequest request) { 
    Mono<Person> person = request.bodyToMono(Person.class);
    return ServerResponse.ok().build(repository.savePerson(person));
}

我们应该手动执行此操作还是有一些自动方法来执行此操作?

在 Spring 5.0 版中,没有在功能端点中自动进行验证的方法,因此必须手动进行验证。

虽然目前没有这样做的具体计划,但我们可能会在未来添加某种验证。但即便如此,它也将是一个显式方法调用,而不是一种自动机制。总的来说,功能端点模型设计得比基于注释的模型更明确。

在当前版本 (2.0.4.RELEASE) 中,无法使用句柄进行自动验证,但是您始终可以像这样进行手动验证:

@Slf4j
@Component
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@RequiredArgsConstructor
public class MyHandlerValidator implements HandlerValidator<MyResource> {

    Validator validator;

    @Override
    public void callValidator(final MyResource fdr) {
        final DataBinder binder = new DataBinder(fdr);
        binder.setValidator(validator);
        binder.validate();

        if (binder.getBindingResult().hasErrors()) {
            final String reason = binder.getBindingResult().getFieldError().toString();
            log.error(reason);
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, reason);
        }
    }   
}

问题在于,您应该像自动验证那样抛出 WebExchangeBindException,但是我无法创建 MethodParameter 是创建此异常的依赖项。

更新: Spring 向我们展示了一种与我的解决方案类似的方法,但我认为 documentation

还不够

正如 arjen-poutsma 所说,似乎没有办法 运行 在 Spring 5 个功能端点上进行自动验证。

Spring文档对此不是很清楚,也没有建议任何方法。

this Baeldung article 上,您会找到关于如何使用这种方法 运行 验证的想法(免责声明:我是这篇文章的作者:))

简而言之,您可以按照以下步骤操作:

  1. 实施 Spring 验证器来评估您的资源
  2. 使用任何处理程序在处理请求时将遵循的基本过程创建一个摘要 class,留待 children class 在数据有效时做什么
  3. 让你的请求处理程序class扩展这个抽象class,实现这个抽象方法,说明它期望的主体,以及需要使用什么验证器来验证它

编辑:

我一直在关注this related Spring issue, and it seems we now count with official documentation regarding this subject: https://github.com/spring-projects/spring-framework/blob/master/src/docs/asciidoc/web/webflux-functional.adoc#validation

建议的方法是按照文章中的说明使用验证器。