简体   繁体   English

将 Avro 二进制字符串转换为 Json

[英]Converting Avro Binary String to Json

I have a String in Avro Binary Format.我有一个 Avro 二进制格式的字符串。 I want to convert the String to json. Can someone please guide me?.我想将字符串转换为 json。有人可以指导我吗? I tried using the solutions available online It did not work.我尝试使用在线可用的解决方案它没有用。

public String avroToJson(byte[] avro) throws IOException {
        boolean pretty = false;
        GenericDatumReader<GenericRecord> reader = null;
        JsonEncoder encoder = null;
        ByteArrayOutputStream output = null;
        try {
            reader = new GenericDatumReader<GenericRecord>();
            InputStream input = new ByteArrayInputStream(avro);
            DataFileStream<GenericRecord> streamReader = new DataFileStream<GenericRecord>(input, reader);
            output = new ByteArrayOutputStream();
            Schema schema = streamReader.getSchema();
            DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
            encoder = EncoderFactory.get().jsonEncoder(schema, output, pretty);
            for (GenericRecord datum : streamReader) {
                writer.write(datum, encoder);
            }
            encoder.flush();
            output.flush();
            return new String(output.toByteArray());
        } finally {
            try {
                if (output != null) output.close();
            } catch (Exception e) {
            }
        }
    }

I am converting the my String to byte array using getBytes() and passing it to this function. I am getting this exception.我正在使用 getBytes() 将我的字符串转换为字节数组并将其传递给此 function。我收到此异常。 Exception in thread "main" org.apache.avro.InvalidAvroMagicException: Not an Avro data file.线程“main”中的异常 org.apache.avro.InvalidAvroMagicException:不是 Avro 数据文件。

Avro specifies a binary format for serializing one object, but also a Object Container File (also known as data file) which can hold many objects in a useful way for file access. Avro 指定了一种二进制格式,用于序列化一个 object,以及一个Object 容器文件(也称为数据文件),它可以以一种有用的方式保存许多对象以进行文件访问。

DataFileStream expects the container file, but from your description, it looks like you have a single serialized instance. DataFileStream需要容器文件,但从您的描述来看,您似乎有一个序列化实例。

You probably want something like:你可能想要这样的东西:

  public String avroToJson(Schema schema, byte[] avroBinary) throws IOException {
    // byte to datum
    DatumReader<Object> datumReader = new GenericDatumReader<>(schema);
    Decoder decoder = DecoderFactory.get().binaryDecoder(avroBinary, null);
    Object avroDatum = datumReader.read(null, decoder);

    // datum to json
    String json = null;
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
      DatumWriter<Object> writer = new GenericDatumWriter<>(schema);
      JsonEncoder encoder = EncoderFactory.get().jsonEncoder(schema, baos, false);
      writer.write(avroDatum, encoder);
      encoder.flush();
      baos.flush();
      return new String(baos.toByteArray(), StandardCharsets.UTF_8);
    }
  }

Note that this means you must know the schema in advance to deserialize the binary data.请注意,这意味着您必须提前知道架构才能反序列化二进制数据。 If it were an Avro data file, you could get the schema from the file metadata.如果它Avro 数据文件,您可以从文件元数据中获取架构。

On this line: Object avroDatum = datumReader.read(null, decoder);在这一行: Object avroDatum = datumReader.read(null, decoder);

I am getting exception:org.apache.avro.AvroRuntimeException: Malformed data.我收到异常:org.apache.avro.AvroRuntimeException:格式错误的数据。 Length is negative: -1长度为负:-1

Did anyone successfully convert AVRO binary to JSON > Please share.有没有人成功地将 AVRO 二进制转换为 JSON > 请分享。

With generics:使用 generics:

public <T extends SpecificRecordBase> String convertAvroToJson(T payload) throws Exception {

    DatumWriter<T> writer = new SpecificDatumWriter<T>(payload.getSchema());
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    byte[] payloadJsonBytes;

    try{

        Encoder jsonEncoder = EncoderFactory.get().jsonEncoder(payload.getSchema(), stream);
        writer.write(payload, jsonEncoder);
        jsonEncoder.flush();
        payloadJsonBytes = stream.toByteArray();

    } catch (IOException e) {
        throw new Exception("Cannot convert avro to JSON! ", e);
    }

    String payloadJson = new String(payloadJsonBytes, StandardCharsets.UTF_8);

    return payloadJson;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM