如何在 Avro 中从 GenericRecord 转换为 SpecificRecord 以获得兼容的模式

How to convert from GenericRecord to SpecificRecord in Avro for compatible schemas

Avro SpecificRecord(即生成的 java 类)是否与模式演变兼容? IE。如果我有 Avro 消息源(在我的例子中是 kafka)并且我想将这些消息反序列化为特定的记录,是否可以安全地进行?

我看到的:

即使消息兼容,这也是一个问题。

如果我能找到新的模式(使用例如 confluent 模式注册表),我可以反序列化为 GenericRecord,但似乎没有办法从 genericrecord 映射到不同模式的 specificrecord..

MySpecificType message = (T SpecificData.get().deepCopy(MySpecificType.SCHEMA$, genericMessage);

在很多地方都提到了 Deepcopy,但它使用索引所以不起作用..

当您拥有两个模式并且它们兼容时,是否有任何安全的方法在两个 avro 对象之间进行映射?即使我可以从 genercrecord 映射到 genericrecord,这也可以做到,然后我可以使用深度复制技巧来完成这项工作。

这里有针对特定数据类型转换的示例测试。都在配置'specificDeserializerProps'

https://github.com/confluentinc/schema-registry/blob/master/avro-serializer/src/test/java/io/confluent/kafka/serializers/KafkaAvroSerializerTest.java

我添加了以下配置并根据需要获取了特定类型。

HashMap<String, String> specificDeserializerProps = new HashMap<String, String>();
specificDeserializerProps.put(KafkaAvroDeserializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "bogus");
specificDeserializerProps.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, "true");
specificAvroDeserializer = new KafkaAvroDeserializer(schemaRegistry, specificDeserializerProps);

希望对您有所帮助

默认情况下,KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG 设置为 false,因此您的 KafkaAvroDeserializer 默认会生成一个 GenericData$Record,而不是您想要的对象(avro 生成 class)。

正如@JARC 所说,您可以通过编程方式启用它。

如果你在Spring引导项目中使用它,这样设置:

spring.kafka.consumer.value-deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer
spring.kafka.consumer.properties.specific.avro.reader=true