Java Avro-反序列化POJO

Java Avro-反序列化POJO,java,web-services,serialization,apache-kafka,avro,Java,Web Services,Serialization,Apache Kafka,Avro,我是阿夫罗的新手,卡夫卡最近几天一直在发送卡夫卡主题的序列化数据。。。没有成功 让我解释一下我想要实现的目标: 在制作人方面,我通过SOAP接收数据,并发送卡夫卡主题的内容。我使用CXF从WSDL生成POJO,并编写了相应的模式。 我试图做的是序列化CXF未经签名的对象,并在我的卡夫卡主题中发送它们 在web上的大多数示例中,Avro记录是使用已知的模式(或数据类型)生成的,但在本例中,我不知道序列化数据时将使用哪个模式。 因此,我动态获取消息类型(通过CXF拦截器)并通过以下方式序列化: //

我是阿夫罗的新手,卡夫卡最近几天一直在发送卡夫卡主题的序列化数据。。。没有成功

让我解释一下我想要实现的目标:

在制作人方面,我通过SOAP接收数据,并发送卡夫卡主题的内容。我使用CXF从WSDL生成POJO,并编写了相应的模式。 我试图做的是序列化CXF未经签名的对象,并在我的卡夫卡主题中发送它们

在web上的大多数示例中,Avro记录是使用已知的模式(或数据类型)生成的,但在本例中,我不知道序列化数据时将使用哪个模式。 因此,我动态获取消息类型(通过CXF拦截器)并通过以下方式序列化:

// get unmarshaled POJO
MessageContentsList objs = MessageContentsList.getContentsList(message);
Object obj = objs.get(0);

EncoderFactory factory = EncoderFactory.get();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Encoder encoder = factory.directBinaryEncoder(out, null);

// getting schema from class name (first approach)
String scName = obj.getClass().getSimpleName();
InputStream avroRes = this.getClass().getClassLoader().getResourceAsStream(scName);
Schema schema = new Schema.Parser().parse(avroRes);

ReflectDatumWriter<Object> writer = new ReflectDatumWriter<Object>(schema);
writer.write(obj, encoder);
encoder.flush();
out.close();

KeyedMessage< String, byte[]> kMessage = new KeyedMessage<String, byte[]>("mytopic", out.toByteArray());
producer.send(kMessage);
//获取取消编组的POJO
messagecontentslistobjs=MessageContentsList.getContentsList(message);
Object obj=objs.get(0);
EncoderFactory=EncoderFactory.get();
ByteArrayOutputStream out=新建ByteArrayOutputStream();
编码器编码器=factory.directBinaryEncoder(输出,空);
//从类名获取架构(第一种方法)
字符串scName=obj.getClass().getSimpleName();
InputStream avroRes=this.getClass().getClassLoader().getResourceAsStream(scName);
Schema Schema=newschema.Parser().parse(avroRes);
ReflectDatumWriter=新的ReflectDatumWriter(模式);
writer.write(obj,编码器);
encoder.flush();
out.close();
KeyedMessagekMessage=newkeyedMessage(“mytopic”,out.toByteArray());
producer.send(kMessage);
通过这种方式,我可以发送有关主题的数据,但无法从传入消息中获取模式

有没有办法:

  • 阅读来自Kafka主题的消息并获取用于序列化的模式
  • 在消费和反序列化时将通用记录映射到POJO
当数据类型未知时,发送卡夫卡主题的Avro记录的“最佳”做法是什么

也许我在阅读Avro文档时漏掉了一些东西,没有按预期使用它


感谢您的帮助……

发送到卡夫卡主题的消息应该对模式和Avro记录进行编码。如果在每条消息中发送模式的开销过大,则改为发送模式的标识符。消息使用者可以使用标识符从数据库检索完整的架构定义。例如,这将在消息的第一个字节中写入模式标识符:

ByteArrayOutputStream out = new ByteArrayOutputStream();

schema = getSchema(object);
int id = schemaRegistry.register(subject, schema);
out.write(MAGIC_BYTE);
out.write(ByteBuffer.allocate(idSize).putInt(id).array());

BinaryEncoder encoder = encoderFactory.directBinaryEncoder(out, null);
DatumWriter<Object> writer;
if (object instanceof SpecificRecord) {
  writer = new SpecificDatumWriter<Object>(schema);
} else {
  writer = new GenericDatumWriter<Object>(schema);
}
writer.write(object, encoder);
encoder.flush();

byte[] bytes = out.toByteArray();
out.close();
return bytes;
ByteArrayOutputStream out=newbytearrayoutputstream();
schema=getSchema(对象);
intid=schemaRegistry.register(主题,模式);
out.write(魔法字节);
out.write(ByteBuffer.allocate(idSize.putInt(id.array());
BinaryEncoder=encoderFactory.directBinaryEncoder(out,null);
DatumWriter;
if(SpecificRecord的对象实例){
writer=新的SpecificDatumWriter(模式);
}否则{
writer=新的GenericDatumWriter(模式);
}
writer.write(对象、编码器);
encoder.flush();
byte[]bytes=out.toByteArray();
out.close();
返回字节;

模式标识符应放在卡夫卡消息的哪一部分?