package com.test.springboot.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.avro.Schema;
import org.apache.avro.file.DataFileReader;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.BinaryDecoder;
import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.io.JsonDecoder;
import org.apache.avro.io.JsonEncoder;
import org.apache.avro.reflect.ReflectData;
import org.apache.avro.reflect.ReflectDatumReader;
import org.apache.avro.reflect.ReflectDatumWriter;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public final class AvroHelper {
private AvroHelper() {
// not instantiable
}
public static <T> T fromAvro(byte[] payload, Class<T> schemaType, boolean allowNull) {
Schema schema = createSchema(schemaType, allowNull);
return fromAvro(payload, schema);
}
public static <T> T fromAvro(byte[] payload, Schema schema) {
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(payload)) {
DatumReader<T> datumReader = new ReflectDatumReader<>(schema);
BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(inputStream, null);
T datum = null;
while (!binaryDecoder.isEnd()) {
datum = datumReader.read(datum, binaryDecoder);
}
return datum;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static <T> List<T> fromAvroList(byte[] payload, Schema schema) {
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(payload)) {
DatumReader<T> datumReader = new ReflectDatumReader<>(schema);
BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(inputStream, null);
List<T> datumList = new ArrayList<>();
while (!binaryDecoder.isEnd()) {
T datum = null;
datum = datumReader.read(datum, binaryDecoder);
datumList.add(datum);
}
return datumList;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static byte[] serializePrimary(Schema schema, File file) throws IOException {
byte[] bytes = null;
DatumReader<GenericRecord> datumReader = new GenericDatumReader<GenericRecord>();
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, datumReader);
DatumWriter<GenericRecord> datumWriter = new SpecificDatumWriter<GenericRecord>(schema);
ByteArrayOutputStream out = new ByteArrayOutputStream();
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null);
GenericRecord data = null;
while (dataFileReader.hasNext()) {
data = dataFileReader.next(data);
datumWriter.write(data, encoder);
encoder.flush();
}
bytes = out.toByteArray();
return bytes;
}
public static <T> byte[] toAvro(T object, Class<T> schemaType, boolean allowNull) {
Schema schema = createSchema(schemaType, allowNull);
return toAvro(object, schema);
}
public static <T> byte[] toAvro(T object, Schema schema) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
DatumWriter<T> datumWriter = new ReflectDatumWriter<>(schema);
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(outputStream, null);
datumWriter.write(object, encoder);
encoder.flush();
outputStream.flush();
return outputStream.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static <T> String fromAvroToJson(byte[] avroBytes, Class<T> schemaType, boolean allowNull) {
Schema schema = createSchema(schemaType, allowNull);
return fromAvroToJson(avroBytes, schema);
}
public static String fromAvroToJson(byte[] avroBytes, Schema schema) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
DatumReader<Object> datumReader = new GenericDatumReader<>(schema);
DatumWriter<Object> datumWriter = new GenericDatumWriter<>(schema);
BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(avroBytes, null);
JsonEncoder jsonEncoder = EncoderFactory.get().jsonEncoder(schema, outputStream);
Object datum = null;
while (!binaryDecoder.isEnd()) {
datum = datumReader.read(datum, binaryDecoder);
datumWriter.write(datum, jsonEncoder);
jsonEncoder.flush();
}
outputStream.flush();
return outputStream.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static <T> byte[] fromJsonToAvro(String json, Class<T> schemaType, boolean allowNull) {
Schema schema = createSchema(schemaType, allowNull);
return fromJsonToAvro(json, schema);
}
public static byte[] fromJsonToAvro(String json, Schema schema) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
DatumReader<Object> datumReader = new GenericDatumReader<>(schema);
DatumWriter<Object> datumWriter = new GenericDatumWriter<>(schema);
BinaryEncoder binaryEncoder = EncoderFactory.get().binaryEncoder(outputStream, null);
JsonDecoder jsonDecoder = DecoderFactory.get().jsonDecoder(schema, json);
Object datum = null;
while (true) {
try {
datum = datumReader.read(datum, jsonDecoder);
} catch (EOFException eofException) {
break;
}
datumWriter.write(datum, binaryEncoder);
binaryEncoder.flush();
}
outputStream.flush();
return outputStream.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Schema createSchema(Class<?> schemaType) {
return createSchema(schemaType, false);
}
public static Schema createSchema(Class<?> schemaType, boolean allowNull) {
return allowNull
? ReflectData.AllowNull.get().getSchema(schemaType)
: ReflectData.get().getSchema(schemaType);
}
public static Schema createSchema(String input) {
return new Schema.Parser().parse(input);
}
public static Schema createSchema(File input) throws IOException {
return new Schema.Parser().parse(input);
}
/**
* 二进制序列化
*
* @param t AVRO生成的对象
* @param <T> AVRO类型
* @return
*/
public static <T> byte[] binarySerializable(T t) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BinaryEncoder binaryEncoder = EncoderFactory.get().binaryEncoder(out, null);
DatumWriter<T> writer = new SpecificDatumWriter<T>((Class<T>) t.getClass());
try {
writer.write(t, binaryEncoder);
binaryEncoder.flush();
out.flush();
} catch (IOException e) {
log.error("binarySerializable error");
e.printStackTrace();
}
log.debug("ByteArrayOutputStream = {}",new String(out.toByteArray()));
return out.toByteArray();
}
/**
* 二进制反序列化
*
* @param bytes
* @param tClass
* @param <T>
* @return
*/
public static <T> T binaryDeserialize(byte[] bytes, Class<T> tClass) {
try {
BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(bytes, null);
DatumReader<T> datumReader = new SpecificDatumReader<T>(tClass);
T read = datumReader.read(null, binaryDecoder);
return read;
} catch (IOException e) {
log.error("binaryDeserialize error");
e.printStackTrace();
}
return null;
}
/**
* 二进制反序列化
*
* @param bytes
* @param schema
* @param <T>
* @return
*/
public static <T> T binaryDeserialize(byte[] bytes, Schema schema) {
try {
BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(bytes, null);
DatumReader<T> datumReader = new SpecificDatumReader<T>(schema);
T read = datumReader.read(null, binaryDecoder);
return read;
} catch (IOException e) {
log.error("binaryDeserialize error");
e.printStackTrace();
}
return null;
}
/**
* json序列化
*
* @param t
* @param <T>
* @return
*/
public static <T> byte[] jsonSerializable(T t, Schema schema) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
Encoder jsonEncoder = EncoderFactory.get().jsonEncoder(schema, out);
DatumWriter<T> writer = new SpecificDatumWriter<T>(schema);
writer.write(t, jsonEncoder);
jsonEncoder.flush();
out.flush();
} catch (IOException e) {
log.error("jsonSerializable error");
e.printStackTrace();
}
log.info("json序列化的String为 = {}", new String(out.toByteArray()));
return out.toByteArray();
}
/**
* json反序列化
*
* @param schema
* @param byteArrayInputStream
* @param <T>
* @return
*/
public static <T> T jsonDeserialize(Schema schema, ByteArrayInputStream byteArrayInputStream) {
try {
Decoder jsonDecoder = DecoderFactory.get().jsonDecoder(schema, byteArrayInputStream);
DatumReader<T> datumReader = new SpecificDatumReader<T>(schema);
T read = datumReader.read(null, jsonDecoder);
return read;
} catch (Exception e) {
log.error("jsonDeserialize error");
e.printStackTrace();
}
return null;
}
}
AvroHelper反序列化工具
于 2022-11-04 10:35:57 首次发布