【问题标题】:@Valid @Payload on @KafkaHandler – bug or missing feature?@KafkaHandler 上的@Valid @Payload – 错误或缺少功能?
【发布时间】:2021-01-09 17:15:59
【问题描述】:

我们将 Spring Kafka 与 Spring Boot(所有最新版本)一起使用。我们将 Kafka 消息的处理切换到 @KafkaHandler 带注释的方法,并期望 @Valid/@Validated@Payload 一起确保有效负载验证,但这并没有发生。此功能适用于@KafkaListener,是否也适用于@KafkaHandler

@KafkaListener(...)
@Component
public class NotificationListener {

    @KafkaHandler
    public void handleV1(@Payload @Valid NotificationV1 notification) {

谢谢。

【问题讨论】:

    标签: spring spring-boot spring-kafka


    【解决方案1】:

    Validator 不适用于这种情况,因为我们只是没有为此目的到达 PayloadMethodArgumentResolver

    多方法@KafkaListener 的目标载荷在我们调用方法之前解析,因为我们肯定需要知道调用哪个方法。这样的逻辑是在InvocableHandlerMethod.getMethodArgumentValues()

            args[i] = findProvidedArgument(parameter, providedArgs);
            if (args[i] != null) {
                continue;
            }
            ...
            try {
                args[i] = this.resolvers.resolveArgument(parameter, message);
            }
    

    Validator 功能在那些resolvers 中完成。 findProvidedArgument() 为我们提供了在执行之前转换的有效负载,这里我们只是不检查参数上的任何注释。

    当我们选择了一个处理程序并在调用它之前,我们可能需要将验证逻辑轮询到DelegatingInvocableHandler...

    请随意提出 GitHub 问题,这样我们就不会忘记需要以某种方式解决这个问题。

    【讨论】:

    【解决方案2】:

    @KafkaListener之所以和@Valid注解一起工作,是因为它就像一个restful控制器端点,是服务的入口。团队致力于在这些情况下添加对验证工作的支持,可以发现这种验证机制是added in 2018

    至于@KafkaHandler,我对spring-kafka不是很熟悉,但是如果验证不起作用,那就说明团队没有添加对这种情况的支持。我建议您使用Spring Boot Method Validation Feature,它适用于所有spring 托管bean 和所有标准验证注释,例如@Size。最后一件事,小心验证失败时抛出的异常。

    【讨论】:

    • 关于Spring Boot中验证的更多信息,我写了一个answer,给出了很多参考文章。
    • 我认为服务验证和控制器端点验证是不同的主题。我猜 Spring Kafka 依赖于 Spring Messaging,并且有不同的路径来确保验证。我能够将其追踪到PayloadMethodArgumentResolver。我检查了此解析器是否已正确自动配置,并且 @KafkaListener 解析器已正确应用,但不适用于 @KafkaHandler
    • 为了清楚起见,有两对。 Controller/Service、KafkaListener/KafkaHandler、Controller 和 KafkaListener 都自动与 @Valid 一起工作,因为它们被增强为可以这样工作。你深入PayloadMethodArgumentResolver 了解 KafkaListener,我也深入了解RequestResponseBodyMethodProcessor 了解控制器验证机制。至于Service/KafakaHandler,在我看来它们是同一类东西,Spring让它们的验证工作不是那么安静,所以我建议你使用Spring Boot Method Validation Feature来处理它们。
    • 我做了一些搜索,我提供的比较不是那么准确。我会在这个主题上做更多的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    相关资源
    最近更新 更多