如何在Avro反序列化后将GenericArray转换为List?

时间:2017-06-05 11:43:10

标签: java avro

下面是我的程序,我在其中执行从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());
}

}

0 个答案:

没有答案