我试图利用以下图表和JSON数据生成Avro GenericRecord。
Avro schema
{
"type": "record",
"name": "Person",
"fields": [
{
"name": "name",
"type": "string"
},
{
"name": "age",
"type": "int"
},
{
"name": "city",
"type": "string"
},
{
"name": "gender",
"type": {
"type": "enum",
"name": "Gender",
"symbols": ["MALE", "FEMALE"]
}
}
]
}
JSON数据
{"name": "John", "age": 30, "city": "New York", "gender": "MALE"}
守则一用于生成通用记录。
public class Main {
public static void main(String[] args) throws IOException {
Schema schema = readSchema();
JsonNode data = readData();
GenericRecord genericRecord = convertJsonToAvro(data, schema);
System.out.println(genericRecord);
}
public static GenericRecord convertJsonToAvro(JsonNode jsonNode, Schema avroSchema) throws IOException {
DatumReader<GenericRecord> reader = new GenericDatumReader<>(avroSchema);
Decoder decoder = DecoderFactory.get().jsonDecoder(avroSchema, jsonNode.toString());
return reader.read(null, decoder);
}
private static Schema readSchema() throws IOException {
InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("schemas/person.avsc");
return new Schema.Parser().parse(inputStream);
}
private static JsonNode readData() throws IOException {
InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("sample_data/person.json");
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(inputStream, JsonNode.class);
}
}
从上述法典来看,我能够成功地产生一种通用记录。 但是,当图谋领域改成像以下这样的选择领域时,就会犯错误。
D. 任择领域
{
"name": "gender",
"type": [
"null",
{
"type": "enum",
"name": "Gender",
"symbols": ["MALE", "FEMALE"]
}
],
"default": null
}
错误
Exception in thread "main" org.apache.avro.AvroTypeException: Expected start-union. Got VALUE_STRING
at org.apache.avro.io.JsonDecoder.error(JsonDecoder.java:511)
at org.apache.avro.io.JsonDecoder.readIndex(JsonDecoder.java:430)
at org.apache.avro.io.ResolvingDecoder.readIndex(ResolvingDecoder.java:282)
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:188)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:161)
at org.apache.avro.generic.GenericDatumReader.readField(GenericDatumReader.java:260)
at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:248)
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:180)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:161)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:154)
at com.generic.Main.convertJsonToAvro(Main.java:27)
at com.generic.Main.main(Main.java:20)
FAILURE: Build failed with an exception.
我非常赞赏有人能够解释这里发生的情况以及纠正这一错误的方法。 我知道allegro/json-avro-converter,但我不想这样做。 守则的例子将非常有益。
请找到上述法典所用的属性。
implementation group: org.apache.avro , name: avro , version: 1.11.3
implementation group: com.fasterxml.jackson.core , name: jackson-core , version: 2.16.0