json to avro解码-avrotypeexception:未找到预期的字段名

2mbi3lxu  于 2021-06-21  发布在  Flink
关注(0)|答案(2)|浏览(394)

我使用的是avro1.8.2,我试图将json转换成genericord

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。我读过其他关于使用模式的帖子,比如 {"name":"frm","type":["null","string"],"default": "null"} 但这些都不管用
谢谢

j8ag8udp

j8ag8udp1#

我唯一能让它工作的方法是将它转换成实际生成的类,该类扩展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)
nvbavucw

nvbavucw2#

所有字段在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不能被引用)

相关问题