我有一个User类,我将其作为avro(使用Confluent avro序列化程序和模式注册表)将其发布并发布到Kafka主题。我让消费者将数据打印到控制台,它工作正常。我现在尝试的是从这些数据创建原始对象。例如,我正在发布" User"对象作为卡夫卡主题的avro。我正在尝试在使用它之后重新创建该用户对象(而不是控制台输出)。这可能吗?
以下是我的代码
用户类
public class User {
int id;
String name;
public User(){}
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
消费者代码
User user = new User();
Properties props = new Properties();
props.put("bootstrap.servers", "127.0.0.1:9092");
props.put("group.id", "avro-consumer-group");
props.put("key.deserializer", io.confluent.kafka.serializers.KafkaAvroDeserializer.class);
props.put("value.deserializer", io.confluent.kafka.serializers.KafkaAvroDeserializer.class);
props.put("schema.registry.url","http://127.0.0.1:8081");
KafkaConsumer<String, GenericRecord> consumer = new KafkaConsumer<String, GenericRecord>(props);
consumer.subscribe(Arrays.asList("avrotesttopic"));
System.out.println("Subscribed to topic " + "avrotesttopic");
while (true) {
ConsumerRecords<String, GenericRecord> records = consumer.poll(100);
for (org.apache.kafka.clients.consumer.ConsumerRecord<String, GenericRecord> record : records){
System.out.printf("value = %sn",record.value());
//output-> value = {"id": 10, "name": "testName"}
}
}
由于
答案 0 :(得分:1)
考虑到您使用的是KafkaAvroDeserializer,您需要将folloing属性设置为消费者配置的一部分
props.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, "true");
它将允许您获取消费者已经处理的SpecificRecord
而不是GenericRecord
。这是一个例子
https://dzone.com/articles/kafka-avro-serialization-and-the-schema-registry
答案 1 :(得分:0)
您可以将AvroSchema转换为JsonSchema,然后从JsonSchema转换为可以创建POJO类。
将AVRO转换为JSON:
static void convertAvroToJson(InputStream inputStream, OutputStream outputStream, Schema schema)
throws IOException {
DatumReader<Object> reader = new GenericDatumReader<>(schema);
DatumWriter<Object> writer = new GenericDatumWriter<>(schema);
BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(inputStream, null);
JsonEncoder jsonEncoder = EncoderFactory.get().jsonEncoder(schema, outputStream, true);
Object datum = null;
while (!binaryDecoder.isEnd()) {
datum = reader.read(datum, binaryDecoder);
writer.write(datum, jsonEncoder);
jsonEncoder.flush();
}
outputStream.flush();
}
然后将JSONSchema转换为POJO,
https://dzone.com/articles/converting-json-to-pojos-using-java
答案 2 :(得分:0)
这取决于您如何将输入记录序列化为Avro。
如果你的序列化没问题,那么简短的答案就是你在接收记录时必须做出以下改变
ConsumerRecords<String, User> records = consumer.poll(100);
有关完整示例,请参阅this