我正在使用Avro 1.8.2,并试图将JSON转换为GenericRecord
DatumReader<GenericData.Record> datumReader = new GenericDatumReader<>(schema);
Decoder decoder = DecoderFactory.get().jsonDecoder(schema, jsonStr);
datumReader.read(null, decoder)
我从第三方获得JSON数据,并且无法控制这些元素。AVRO模式是
{
"namespace":"com.avro.generated",
"type":"record",
"name":"TestEvent",
"fields":[
{"name":"userId","type":"string"},
{"name":"frm","type":"string"},
{"name":"issuerName","type":"string"},
{"name":"profileId","type":"string"}
]
}
如果我使用这个JSON
{
"userId":"5435tert34tgcb21391f7bda71",
"frm":"somerm",
"issuerName":"somenameorts",
"profileId":"0werwerwer0000-0000-000000000000"
}
它运行良好。但是,如果json不包含frm元素,如下所示
{
"userId":"5435tert34tgcb21391f7bda71",
"issuerName":"somenameorts",
"profileId":"0werwerwer0000-0000-000000000000"
}
然后我得到这个异常
org.apache.avro.AvroTypeException: Expected field name not found: frm.
有什么办法让它发挥作用吗?。我无法控制JSON。我读过其他SO关于使用之类的模式的帖子
{"name":"frm","type":["null","string"],"default": "null"}
但这些都不起作用
感谢
AVRO中的所有字段都是必需的,但您可以提供一个默认值,以便它具有该字段。
{
"namespace":"com.avro.generated",
"type":"record",
"name":"TestEvent",
"fields":[
{"name":"userId","type":["null","string"], "default": null},
{"name":"frm","type":["null","string"], "default": null},
{"name":"issuerName","type":["null","string"], "default": null},
{"name":"profileId","type":["null","string"], "default": null}
]
}
编辑:很抱歉没有阅读你的邮件末尾。当你说它不工作时,错误是什么(另外,请注意,不能引用null(
我能完成这项工作的唯一方法是将其转换为实际生成的类,该类扩展了SpecificRecordBase,并将其转换回GenericRecord。我不知道这是否是一种有效的方法,但只是发布
ObjectMapper mapper = new ObjectMapper();
TestEvent node = mapper.readValue(jsonStr.getBytes(), TestEvent.class);
// This gives the actual Class
我可以使用将其转换回通用记录
Schema schema = TestEvent.getClassSchema();
ReflectDatumWriter datumWriter = new ReflectDatumWriter<>(schema);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(outputStream, null);
datumWriter.write(node, encoder);
encoder.flush();
DatumReader<GenericRecord> datumReader = new GenericDatumReader<>(schema);
BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(outputStream.toByteArray(), null);
datumReader.read(null, decoder)