为kafka消费者使用多个反序列化器

时间:2016-10-24 12:44:14

标签: java serialization properties avro kafka-consumer-api

我是kafka的新手甚至是序列化。到目前为止,我被要求使用简单的代码处理json格式的kafka事件序列化。但现在使用Avro编码器添加了额外的事件。所以现在我希望这个单一的消费者在json中使用StringDeserialzer,而在Avro中使用它的各自的反序列化器。但是如何在同一个属性文件中映射2个反序列化器呢?

private Properties getProps(){
    Properties props = new Properties();
    props.put("group.id", env.getProperty("group.id"));
    props.put("enable.auto.commit", env.getProperty("enable.auto.commit"));
    props.put("key.deserializer", env.getProperty("key.deserializer"));
    props.put("value.deserializer", env.getProperty("value.deserializer"));
    return props;
}//here as only value can be mapped to "key.deserializer" is there anyway to do this

主要方法

KafkaConsumer<String, String> _consumer = new KafkaConsumer<>(getProps());
consumers.add(_consumer);
_consumer.subscribe(new ArrayList<>(topicConsumer.keySet()));

2 个答案:

答案 0 :(得分:0)

您需要提供一个包含两个原始解串器的混合反序列化器。在内部,新的包装解串器必须能够区分两种类型的消息,并将原始字节转发到执行实际工作的正确解串器。

如果你事先无法知道你有什么类型的消息,你也可以尝试一种错误的方法 - 也就是说,默认情况下将它交给一个序列化程序,如果这个失败了(即抛出一个异常)试试第二个之一。

答案 1 :(得分:0)

只需编写一个通用的反序列化器,即可将主题委派给匹配的反序列化器。

public class GenericDeserializer extends JsonDeserializer<Object>
{
    public GenericDeserializer()
    {
    }

    @Override
    public Object deserialize(String topic, Headers headers, byte[] data)
    {
        switch (topic)
        {
        case KafkaTopics.TOPIC_ONE:
            TopicOneDeserializer topicOneDeserializer = new TopicOneDeserializer();
            topicOneDeserializer.addTrustedPackages("com.xyz");
            return topicOneDeserializer.deserialize(topic, headers, data);
        case KafkaTopics.TOPIC_TWO:
            TopicTwoDeserializer topicTwoDeserializer= new TopicTwoDeserializer();
            topicTwoDeserializer.addTrustedPackages("com.xyz");
            return topicTwoDeserializer.deserialize(topic, headers, data);
        }
        return super.deserialize(topic, data);
    }
}