序列化JSON字符串到具有Union字段的Avro对象



我有两个Avro模式,其中一个包含几个联合字段,联合类型是["null", "string"]。另一个模式没有任何联合字段。
我有代表上述两种模式的POJO类。pojo是由avro-tools-1.11.0.jar生成的

我遵循以下方法将JSON转换为Avro对象(不包含任何联合字段的对象)

Decoder decoder = DecoderFactory.get().jsonDecoder(EtmKey.getClassSchema(), "The JSON Input!");
SpecificDatumReader<EtmKey> reader = new SpecificDatumReader<>(EtmKey.getClassSchema());
EtmKey etmKeyDatum = reader.read(null, decoder);
System.out.println("EtmKey topic: " + etmKeyDatum.toString());

EtmKey是Avro模式表示类。

使用上面的代码,我能够成功地生成Avro对象,没有任何问题。我使用的库是org.apache.avro

但是当Avro对象有联合字段时,同一个库不能用于生成Avro对象。它抛出Exception in thread "main" org.apache.avro.AvroTypeException: Expected start-union. Got VALUE_STRING。根据这里的答案,尝试手动转换像"field_5": {"string": "0MI8C..."}这样的字段值,但没有运气。无论如何都不能手动转换

JSON有效负载示例,

{
"field_1": "Apple",
"field_2": "123",
"field_3": "001-123",
"field_4": "TR501",
"field_5": "0MI8...",
"field_6": "0010y...",
"field_7": "2022-12-02T22:21:19.000+0000",
"field_8": "john.doe",
"field_9": "005E00."
}

请注意JSON有效负载字段的名称与Avro类中的名称相同。

在这里,我想深入了解一下如何生成具有联合字段的Avro对象。使用JSON输入。解决方案应该是可靠的,并且需要使用官方插件/依赖项或知名库,如Jackson, Gson。感谢任何资源/代码示例和建议。

通过实现以下代码解决了这个问题,

public static <T> T getAvroRecord(Schema schema, ExtraPayload extraPayload) throws IOException {
ReflectDatumWriter datumWriter = new ReflectDatumWriter(schema);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(outputStream, null);
datumWriter.write(extraPayload, encoder);
encoder.flush();
DatumReader datumReader = new GenericDatumReader(schema);
BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(outputStream.toByteArray(), null);
GenericRecord genericRecord = (GenericRecord) datumReader.read(null, decoder);
return (T) SpecificData.get().deepCopy(schema, genericRecord);
}

调用该方法并将输出分配给所需的类(实体)。

Etm etm = getAvroRecord(Etm.getClassSchema(), sourceData);

Etm是一个使用Avro -tools生成的Avro POJO类

相关内容

  • 没有找到相关文章

最新更新