You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@avro.apache.org by Check Peck <co...@gmail.com> on 2014/12/30 23:40:20 UTC

How to avro binary encode my json string to a byte array?

I have a actual JSON String which I need to avro binary encode to a byte
array. After going through the Apache Avro specification (
http://avro.apache.org/docs/1.7.7/spec.html), I came up with the below code.

I am not sure whether this is the right way to do it or not. Can anyone
take a look whether the way I am trying to avro binary encode my JSON
String is correct or not?. I am using Apache Avro 1.7.7 version.

    public class AvroTest {

        private static final String json = "{" + "\"name\":\"Frank\"," +
"\"age\":47" + "}";
        private static final String schema = "{ \"type\":\"record\",
\"namespace\":\"foo\", \"name\":\"Person\", \"fields\":[ {
\"name\":\"name\", \"type\":\"string\" }, { \"name\":\"age\",
\"type\":\"int\" } ] }";

        public static void main(String[] args) throws IOException {
            byte[] data = jsonToAvro(json, schema);

            String jsonString = avroToJson(data, schema);
            System.out.println(jsonString);
        }

        /**
         * Convert JSON to avro binary array.
         *
         * @param json
         * @param schemaStr
         * @return
         * @throws IOException
         */
        public static byte[] jsonToAvro(String json, String schemaStr)
throws IOException {
            InputStream input = null;
            GenericDatumWriter<Object> writer = null;
            Encoder encoder = null;
            ByteArrayOutputStream output = null;
            try {
                Schema schema = new Schema.Parser().parse(schemaStr);
                DatumReader<Object> reader = new
GenericDatumReader<Object>(schema);
                input = new ByteArrayInputStream(json.getBytes());
                output = new ByteArrayOutputStream();
                DataInputStream din = new DataInputStream(input);
                writer = new GenericDatumWriter<Object>(schema);
                Decoder decoder = DecoderFactory.get().jsonDecoder(schema,
din);
                encoder = EncoderFactory.get().binaryEncoder(output, null);
                Object datum;
                while (true) {
                    try {
                        datum = reader.read(null, decoder);
                    } catch (EOFException eofe) {
                        break;
                    }
                    writer.write(datum, encoder);
                }
                encoder.flush();
                return output.toByteArray();
            } finally {
                try {
                    input.close();
                } catch (Exception e) {
                }
            }
        }

        /**
         * Convert Avro binary byte array back to JSON String.
         *
         * @param avro
         * @param schemaStr
         * @return
         * @throws IOException
         */
        public static String avroToJson(byte[] avro, String schemaStr)
throws IOException {
            boolean pretty = false;
            GenericDatumReader<Object> reader = null;
            JsonEncoder encoder = null;
            ByteArrayOutputStream output = null;
            try {
                Schema schema = new Schema.Parser().parse(schemaStr);
                reader = new GenericDatumReader<Object>(schema);
                InputStream input = new ByteArrayInputStream(avro);
                output = new ByteArrayOutputStream();
                DatumWriter<Object> writer = new
GenericDatumWriter<Object>(schema);
                encoder = EncoderFactory.get().jsonEncoder(schema, output,
pretty);
                Decoder decoder = DecoderFactory.get().binaryDecoder(input,
null);
                Object datum;
                while (true) {
                    try {
                        datum = reader.read(null, decoder);
                    } catch (EOFException eofe) {
                        break;
                    }
                    writer.write(datum, encoder);
                }
                encoder.flush();
                output.flush();
                return new String(output.toByteArray());
            } finally {

            }
        }

    }