Авро сериализовать и десиарализовать список <UUID> - PullRequest
0 голосов
/ 09 сентября 2018

Я не могу понять, как сериализовать List в двоичный формат и десериализовать обратно в List. Я попытался использовать CustomEncoding для этой цели:

public class ListUUIDAsListStringEncoding extends CustomEncoding<List<UUID>> {
    {
        schema = Schema.createArray(Schema.createUnion(Schema.create(Schema.Type.STRING)));
        schema.addProp("CustomEncoding", "com.my.lib.common.schemaregistry.encoding.ListUUIDAsListStringEncoding");
    }

    @Override
    protected void write(Object datum, Encoder out) throws IOException {
        var list = (List<UUID>) datum;
        out.writeArrayStart();
        out.setItemCount(list.size());
        for (Object r : list) {
            if (r instanceof UUID) {
                out.startItem();
                out.writeString(r.toString());
            }
        }
        out.writeArrayEnd();
    }

    @Override
    protected List<UUID> read(Object reuse, Decoder in) throws IOException {
        var newArray = new ArrayList<UUID>();

        for (long i = in.readArrayStart(); i != 0; i = in.arrayNext()) {
            for (int j = 0; j < i; j++) {
                newArray.add(UUID.fromString(in.readString()));
            }
        }

        return newArray;
    }

}

Метод 'write', кажется, проходит правильно, но метод 'read' остановлен с исключением 'java.lang.ArrayIndexOutOfBoundsException: 36' при попытке прочитать строку.

Что я делаю неправильно и как правильно десериализовать данные?

1 Ответ

0 голосов
/ 11 сентября 2018

Решил сам:

Поместите мой класс кодирования здесь, если кому-то это понадобится:

public class ListUuidAsNullableListStringEncoding extends CustomEncoding<List<UUID>> {
    {
        schema = Schema.createUnion(
            Schema.create(Schema.Type.NULL),
            Schema.createArray(Schema.create(Schema.Type.STRING))
        );
    }

    @Override
    protected void write(Object datum, Encoder out) throws IOException {
        if (datum == null) {
            out.writeIndex(0);
            out.writeNull();
        } else {
            out.writeIndex(1);
            out.writeArrayStart();
            out.setItemCount(((List) datum).size());
            for (Object item : (List) datum) {
                if (item instanceof UUID) {
                    out.startItem();
                    out.writeString(item.toString());
                }
            }
            out.writeArrayEnd();
        }
    }

    @Override
    protected List<UUID> read(Object reuse, Decoder in) throws IOException {
        switch (in.readIndex()) {
            case 1:
                var newArray = new ArrayList<UUID>();

                for (long i = in.readArrayStart(); i != 0; i = in.arrayNext()) {
                    for (int j = 0; j < i; j++) {
                        newArray.add(UUID.fromString(in.readString()));
                    }
                }

                return newArray;
            default:
                in.readNull();
                return null;
        }
    }

}
...