下面是我的程序,我在其中执行从GenericArray到ByteArray的序列化过程以及从BytesArray到GenericArray的反序列化过程。在反序列化过程之后,我需要将获得的GenericArray转换为List。
public class AvroGenericSerializer {
private final EncoderFactory encoderFactory = EncoderFactory.get();
private final DecoderFactory decoderFactory = DecoderFactory.get();
/**
* Method to serialize
* @param schema - schema of the object
* @param genericArray - top level element type corresponding to schema
* This can be genericArray or GenericRecord or anything else as per schema
* @return
*/
public byte[] serialize(Schema schema, GenericArray genericArray) {
try {
GenericDatumWriter<GenericArray> writer = new GenericDatumWriter<>(schema);
ByteArrayOutputStream out = new ByteArrayOutputStream();
Encoder binaryEncoder = encoderFactory.binaryEncoder(out, null);
writer.write(genericArray, binaryEncoder);
binaryEncoder.flush();
out.close();
return out.toByteArray();
} catch (Exception e) {
throw new RuntimeException("serialization failed", e);
}
}
/**
* Method to deserialize
* @param schema - avro schema
* @param array - serialized byte[]
* @return
*/
public GenericArray deserialize(Schema schema, byte[] array) {
try {
GenericDatumReader<GenericArray> genericDatumReader = new GenericDatumReader<>(schema);
final GenericArray genericArray = genericDatumReader.read(null, decoderFactory.binaryDecoder(array, null));
return genericArray;
} catch (Exception e) {
throw new RuntimeException("deserialization failed", e);
}
}
/**
* Method to create avro object , GenericArray in this case from the Java object
* @param users - Java object to be serialized
* @param schema - avro schema of the given java object
* @return GenericArray - avro object corresponding to schema
*/
private static GenericArray createGenericArray(List<User> users,Schema schema) {
GenericArray<GenericRecord> avroArray = new GenericData.Array<>(users.size(), schema );
for (User user : users) {
GenericRecord genericRecord = new GenericData.Record(schema.getElementType());
genericRecord.put("name",user.name);
genericRecord.put("gender",user.gender);
genericRecord.put("hgt",user.hgt);
avroArray.add(genericRecord);
}
return avroArray;
}
final static class User {
String name;
String gender;
float hgt;
public User(String name, String gender, float hgt) {
this.name = name;
this.gender = gender;
this.hgt = hgt;
}
}
public static void main(String[] args) {
AvroGenericSerializer genericSerializer = new AvroGenericSerializer();
String schema = "{\"namespace\":\"com.test\",\"name\":\"users\",\"type\":\"array\",\"items\":{\"name\":\"user\",\"type\":\"record\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"gender\",\"type\":\"string\"},{\"name\":\"hgt\",\"type\":\"float\"}]}}";
final Schema avroSchema = new Schema.Parser().parse(schema);
User user1 = new User("mark","male",6.1f);
User user2 = new User("Sara","female",5.2f);
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
GenericArray genericArray = createGenericArray(users,avroSchema);
final byte[] serialized = genericSerializer.serialize(avroSchema, genericArray);
final GenericArray deserialized = genericSerializer.deserialize(avroSchema, serialized);
assert genericArray.equals(deserialized);
System.out.println("before serialization : "+genericArray.toString());
System.out.println("after deserialization : " + deserialized.toString());
}
}