JSON到Avro解码-AvroTypeException:找不到所需的字段名称



我正在使用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)

相关内容

  • 没有找到相关文章

最新更新