反序列化后如何处理SerializationException

反序列化后如何处理SerializationException,serialization,error-handling,deserialization,spring-kafka,Serialization,Error Handling,Deserialization,Spring Kafka,我在SpringKafka设置中使用Avro和模式注册表 我想以某种方式处理在反序列化过程中可能引发的序列化异常 我发现了以下两个资源: 这些资源建议我在反序列化和侦听KafkaNull时返回null,而不是抛出SerializationException。这个解决方案效果很好 然而,我希望能够抛出一个异常,而不是返回null 并提供更好的功能来处理异常。我确实在SpringCloud中找到了一些提到KIP-161的资料,但没有具体介绍SpringKafka 有人知道如何在Spring Bo

我在SpringKafka设置中使用Avro和模式注册表

我想以某种方式处理在反序列化过程中可能引发的
序列化异常

我发现了以下两个资源:

这些资源建议我在反序列化和侦听
KafkaNull
时返回null,而不是抛出
SerializationException
。这个解决方案效果很好

然而,我希望能够抛出一个异常,而不是返回null

并提供更好的功能来处理异常。我确实在SpringCloud中找到了一些提到KIP-161的资料,但没有具体介绍SpringKafka

有人知道如何在Spring Boot中捕获
SerializationException

我使用的是Spring Boot 2.0.2

编辑:我找到了一个解决方案

我宁愿抛出一个异常并捕获它,也不必返回null或
KafkaNull
。我在多个不同的项目中使用我的自定义Avro序列化程序和反序列化程序,其中一些项目不是Spring。如果我更改了Avro序列化程序和反序列化程序,则需要更改其他一些项目,以期望反序列化程序返回null

我想关闭容器,这样我就不会丢失任何消息。生产中不应出现SerializationException。SerializationException应仅在模式注册表关闭或未格式化消息以某种方式发送到生产kafka时发生。无论哪种方式,SerializationException都应该很少发生,如果发生,那么我希望关闭容器,这样就不会丢失任何消息,并且我可以调查这个问题

只需考虑将捕获消费者容器中的所有异常。在我的特定情况下,我只想在出现
SerializationException

public class SerializationExceptionHandler extends ContainerStoppingErrorHandler {

    @Override
    public void handle(Exception thrownException, List<ConsumerRecord<?, ?>> records, Consumer<?, ?> consumer,
                       MessageListenerContainer container) {

        //Only call super if the exception is SerializationException
        if (thrownException instanceof SerializationException) {
            //This will shutdown the container.
            super.handle(thrownException, records, consumer, container);
        } else {
            //Wrap and re-throw the exception
            throw new KafkaException("Kafka Consumer Container Error", thrownException);
        }
    }
}

春天无能为力;反序列化发生在使用者获取任何数据之前。您需要增强反序列化程序

然而,我希望能够抛出一个异常,而不是返回null

这不会有任何帮助,因为卡夫卡不知道如何处理异常。再一次;这一切都发生在数据可用之前,因此返回null(或其他一些特殊值)是最好的技术

编辑


在2.2中,我们添加了一个函数,它委托给实际的反序列化程序并返回null,但在头中有一个异常;然后侦听器容器将其直接传递给错误处理程序,而不是侦听器。

感谢您的澄清。我将继续使用
KafkaNull
,或者尝试AspectJ。我设法找到了一个解决方案。我已经创建了一个自定义异常处理程序并将其传递给容器。
@Bean
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Integer, String>>
kafkaListenerContainerFactory(JpaTransactionManager jpa, KafkaTransactionManager<?, ?> kafka) {

    ConcurrentKafkaListenerContainerFactory<Integer, String> factory =
            new ConcurrentKafkaListenerContainerFactory<>();

    factory.setConsumerFactory(consumerFactory());
    factory.setConcurrency(1);
    factory.getContainerProperties().setPollTimeout(3000);

    factory.getContainerProperties().setErrorHandler(new SerializationExceptionHandler());

    factory.getContainerProperties().setTransactionManager(chainedTxM(jpa, kafka));
    return factory;
}