Flink 反序列化架构问题

时间:2021-07-13 17:21:50

标签: java json apache-flink avro

我尝试使用 FlinkKafkaConsumer 反序列化基于来自 flink 上游的 avro 模式的 json。传入的消息成功反序列化为 JSONObject,但是当我尝试对 JSONObject 执行某些操作时,我收到错误消息,指出它不是有效的 JSONObject,因为它包含一些转义字符。

下面是上游系统使用的 Avro 序列化模式,基本上是一个 Spring 启动系统

public class AvroSerializer<T extends SpecificRecordBase> implements Serializer<T> {

    @Override
    public void close() {
        // No-op
    }

    @Override
    public void configure(Map<String, ?> arg0, boolean arg1) {
        // No-op
    }

    @Override
    public byte[] serialize(String topic, T data) {
        try {
            byte[] result = null;

            if (data != null) {

                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                BinaryEncoder binaryEncoder =
                        EncoderFactory.get().binaryEncoder(byteArrayOutputStream, null);

                DatumWriter<T> datumWriter = new GenericDatumWriter<>(data.getSchema());
                datumWriter.write(data, binaryEncoder);

                binaryEncoder.flush();
                byteArrayOutputStream.close();

                result = byteArrayOutputStream.toByteArray();
            }
            return result;
        } catch (IOException ex) {
            throw new SerializationException(
                    "Can't serialize data='" + data + "' for topic='" + topic + "'", ex);
        }
    }
}

以下是 Flink kafka 消费者中的反序列化

public class AvroDeserialization<T> implements DeserializationSchema<T> {

    private static final long serialVersionUID = 4330538776656642778L;

    private final Class<T> avroType;
    private transient DatumReader<T> reader;
    private transient BinaryDecoder decoder;

    public AvroDeserialization(Class<T> avroType) {
        this.avroType = avroType;
    }

    @Override
    public T deserialize(byte[] message) {
        ensureInitialized();
        try {
            decoder = DecoderFactory.get().binaryDecoder(message, decoder);
            return reader.read(null, decoder);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean isEndOfStream(T nextElement) {
        return false;
    }

    @Override
    public TypeInformation<T> getProducedType() {
        return TypeExtractor.getForClass(avroType);
    }

    private void ensureInitialized() {
        if (reader == null) {
            if (org.apache.avro.specific.SpecificRecordBase.class.isAssignableFrom(avroType)) {
                reader = new SpecificDatumReader<T>(avroType);
            } else {
                reader = new ReflectDatumReader<T>(avroType);
            }
        }
    }

    public void deserialize() {
    }
}

作为一种解决方法,我正在替换 json 字符串中的转义字符,如下所示。但它不会永久解决问题,请建议我如何解决问题。

String incomingData = incomingEvent.getData();
int i = incomingData.indexOf("{");
incomingData = incomingData.substring(i);
int p = incomingData.lastIndexOf("}");
incomingData = incomingData.substring(i, p + 1);
incomingData = incomingData.replaceAll("\\\\n\t", "\n");
jSONObject finalEvent = new JSONObject(incomingData.trim())

基本上这是现在工作,但我不确定其他消息它是如何反应的。

0 个答案:

没有答案