【问题标题】:When set ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG to IntegerSerializer in ProducerConfigs in Spring boot kafka, it gives class cast exception在 Spring boot kafka 中的 ProducerConfigs 中将 ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG 设置为 IntegerSerializer 时,会给出类转换异常
【发布时间】:2020-05-25 00:56:55
【问题描述】:

我正在使用这个Spring boot with kafka 设置我的项目。但是当我运行它时它会给org.apache.kafka.common.errors.SerializationException: Can't convert key of class java.lang.Integer to class org.apache.kafka.common.serialization.StringSerializer specified in key.serializer Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String 使用 kafka 模板发送请求时出现此异常。

@EmbeddedKafka(partitions = 1)
@SpringBootTest
class KafkaApplicationTests {

    @Autowired
    private MyKafkaListener listener;

    @Autowired
    private KafkaTemplate<Integer, String> template;

    @Autowired
    private EmbeddedKafkaBroker embeddedKafka;

    @Test
    public void testSimple() throws Exception {
        template.send("annotated1", 0, "foo");
        template.flush();
        assertTrue(this.listener.latch1.await(10, TimeUnit.SECONDS));
    }

    @Configuration
    @EnableKafka
    public class Config {

        @Bean
        ConcurrentKafkaListenerContainerFactory<Integer, String>
        kafkaListenerContainerFactory() {
            ConcurrentKafkaListenerContainerFactory<Integer, String> factory =
                    new ConcurrentKafkaListenerContainerFactory<>();
            factory.setConsumerFactory(consumerFactory());
            return factory;
        }

        @Bean
        public ConsumerFactory<Integer, String> consumerFactory() {
            return new DefaultKafkaConsumerFactory<>(consumerConfigs());
        }

        @Bean
        public Map<String, Object> consumerConfigs() {
            Map<String, Object> props = new HashMap<>();
//          props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, embeddedKafka.getBrokersAsString());
            props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
            return props;
        }

        @Bean
        public ProducerFactory<Integer, String> producerFactory() {
            return new DefaultKafkaProducerFactory<>(producerConfigs());
        }

        @Bean
        public Map<String, Object> producerConfigs() {
            Map<String, Object> props = new HashMap<>();
            props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class);
            props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class);
//          props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, embeddedKafka.getBrokersAsString());
            props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
            return props;
        }

        @Bean
        public KafkaTemplate<Integer, String> kafkaTemplate() {
            return new KafkaTemplate<Integer, String>(producerFactory());
        }

    }
}

但是当我更改 template.send("annotated1", "key-foo", "foo"); 时,它会起作用。我用过

@Bean
public Map<String, Object> producerConfigs() {
    Map<String, Object> props = new HashMap<>();
    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class);
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class);
    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
    return props;
}

这个配置也是如此。但它仍然给了我 原因:java.lang.ClassCastException:java.lang.Integer 无法转换为 java.lang.String

如果有人请帮助我。谢谢

【问题讨论】:

    标签: spring-boot apache-kafka kafka-consumer-api spring-kafka kafka-producer-api


    【解决方案1】:

    需要将主应用类和Config类添加到@SpringBootTest

    @SpringBootTest(classes = { So61985794Application.class, So61985794ApplicationTests.Config.class })
    

    覆盖 Boot 的正常配置。

    【讨论】:

    • 感谢您的帮助。但我已经弄清楚我错过了什么。 @Bean public KafkaTemplate&lt;Integer, String&gt; kafkaTemplate() { return new KafkaTemplate&lt;Integer, String&gt;(producerFactory()); } 所以在这里我的 Key 是 Integer 并且 value 是 String 对于生产者工厂。但是我已经设置了props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class); 所以我把那个改成 StringSerializer.class 并且我已经从这个代码中删除了 0 并且它工作了。
    • 但我有一个担心。当我将 0 整数更改为“0”(字符串零)时,它起作用了。你能解释这是为什么吗?我知道默认情况下 ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG 和 ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG 正在使用 StringSerializer.class
    猜你喜欢
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2019-04-09
    • 2020-02-05
    • 2021-01-26
    相关资源
    最近更新 更多