Deserialize an avro BigDecimal custom field and then serialize it to String

110 Views Asked by At

I receive an avro file with this schema for some field inside it, that should deserialize to BigDecimal.

{
   "name": "positionQuantity",
   "type": [
        {
           "type": "fixed",
            "name": "fixed",
            "namespace": "topLevel.payload.positionQuantity",
            "size": 10,
            "logicalType": "decimal",
            "precision": 22,
            "scale": 2
        },
        "null"
    ]
},

I used this piece of code until now and it worked ok for every other fields but not for this field:

public static JsonNode toJsonNode(GenericRecord record) {
     try (var outStream = new ByteArrayOutputStream()) {
                var datumWriter = new GenericDatumWriter<>(record.getSchema());
                var binaryEncoder = EncoderFactory.get().directBinaryEncoder(outStream, null);
                datumWriter.write(record, binaryEncoder);
                binaryEncoder.flush();
                return outStream.toByteArray();
                return objectMapper.readerFor(ObjectNode.class)
                    .with(new AvroSchema(record.getSchema()))
                    .readValue(b);
            }
}

Now this field gets deserialized like this (when I do another serialization of the result using JsonNode.toString)

"positionQuantity":"AAAAAAAAAAFAig=="

If I use avro library to directly serialize it to string with this recommended code:

    @SneakyThrows
    public static String avroToJson(GenericRecord datum, Schema schema) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        DatumWriter<Object> writer = new GenericDatumWriter<>(schema);
        JsonEncoder encoder = EncoderFactory.get().jsonEncoder(schema, output, false);
        writer.write(datum, encoder);
        encoder.flush();
        output.flush();
        return new String(output.toByteArray(), "UTF-8");
    }

I get this result:

"positionQuantity":{"topLevel.payload.positionQuantity.fixed":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001@Š"}

which is not why I want.

I would like to get this result:

"positionQuantity": "850.21" 

or at least

"positionQuantity": 850.21

So:

  • how should I serialize BigDecimal? (intermediary problem)
  • how do I get to the wanted results?

PS I think that changing type to bytes might solve the problem of auto-deserializing using my code, but I must try it

0

There are 0 best solutions below