Protostuff не может быть преобразован в байты Protobuf? ⇐ JAVA
-
Гость
Protostuff не может быть преобразован в байты Protobuf?
В Protostuff есть ProtobufIOUtil, который, судя по всему, способен преобразовывать объекты Java в байты protobuf. В настоящее время обнаружено, что при работе с типами карт могут существовать различия.
Например:
@Getter @Сеттер публичный класс пользователя { @Тег(1) частный длинный идентификатор пользователя; @Тег(2) частное имя строки; @Тег(3) частная карта Map map = new HashMap(); // Поле типа карты } syntax="proto3"; сообщение пользователя { int64 uid = 1; имя строки = 2; карта карта = 3; } Тест:
публичный класс Test { public static void main(String[] args) выдает InvalidProtocolBufferException { Пользователь пользователя = новый пользователь(); user.setUid(1); user.setName("s"); Map map = new HashMap(); карта.пут(1L, 1); user.setMap(карта); Схема Schema = RuntimeSchema.getSchema(User.class); byte[] bytes = ProtobufIOUtil.toByteArray(пользователь, схема, LinkedBuffer.allocate()); System.out.println(Arrays.toString(байты)); UserOuterClass.User pbUser = UserOuterClass.User.newBuilder() .setUid(1) .setName("s") .putMap(1, 1) .строить(); System.out.println(Arrays.toString(pbUser.toByteArray())); UserOuterClass.User newPbUser = UserOuterClass.User.parseFrom(байты); System.out.println(newPbUser.toString()); } } Вывод на консоль:
[8, 1, 18, 1, 115, 26, 6, 10, 4, 8, 1, 16, 1] [8, 1, 18, 1, 115, 26, 4, 8, 1, 16, 1] пользовательский идентификатор: 1 имя: "с" карта { ключ: 0 значение: 0 } Зависимости:
io.protostuff ядро прототипа 1.7.4 io.protostuff среда выполнения прототипа 1.7.4 io.protostuff protostuff-runtime-register 1.7.4 com.google.protobuf protobuf-java 3.21.8 Байты, сгенерированные с помощью ProtobufIOUtil.toByteArray() в ProtoStuff, отличаются от байтов, сгенерированных в ProtoBuf, когда-то с полями типа Map в классе Pojo.
Структура данных карты, закодированная protobuf, примерно такая: fieldTag, eleLen, eleData, fieldTag, eleLen, eleData.
Байтовые данные, преобразованные из protostuff в protobuf, примерно имеют вид fieldTag, fieldLen, fieldTag, eleLen, eleData, fieldTag, eleLen, eleData.
По сравнению с protobuf здесь есть еще две точки данных: fieldTag, fieldLen.
В любом случае, я хочу, чтобы байты, сгенерированные protostuff, анализировались в protobuf для создания того же объекта, что и исходный объект.
Существует ли какая-либо соответствующая конфигурация для прототипов, которая поддерживает отсутствие написания fieldTag и fieldLen в начале?
Если нет, поддерживает ли protostuff пользовательское кодирование и декодирование (я знаю, что Delegate можно использовать для настройки кодирования и декодирования, но, похоже, это требует написания самостоятельно. Я хочу совместить его с исходным кодированием и декодированием карты, но пока не нашел реализации).
---ОБНОВЛЕНИЕ---
Теперь я решил использовать делегат:
публичный класс MapDelegate { public static Final Delegate MAP_INT_LONG_DELEGATE = новый Delegate() { @Override общественный WireFormat.FieldType getFieldType() { вернуть WireFormat.FieldType.MESSAGE; } @Override public Map readFrom(Input input) выдает IOException { // будет реализовано } @Override public void writeTo (Выходной вывод, число int, значение Map, логическое повторение) выдает IOException { // будет реализовано } @Override public void Transfer (трубопровод, входной ввод, выходной вывод, число int, повторение логического значения) выдает IOException { throw new UnsupportedOperationException("Операция передачи не поддерживается."); } @Override общественный класс typeClass() { вернуть Map.класс; } }; } Обновленный Тест:
публичный класс Test { public static void main(String[] args) выдает InvalidProtocolBufferException { Стратегия DefaultIdStrategy = (DefaultIdStrategy) RuntimeEnv.ID_STRATEGY; Strategy.registerDelegate(MAP_INT_LONG_DELEGATE); ... } } Но понятия не имею, как реализовать readFrom и writeTo.
В Protostuff есть ProtobufIOUtil, который, судя по всему, способен преобразовывать объекты Java в байты protobuf. В настоящее время обнаружено, что при работе с типами карт могут существовать различия.
Например:
@Getter @Сеттер публичный класс пользователя { @Тег(1) частный длинный идентификатор пользователя; @Тег(2) частное имя строки; @Тег(3) частная карта Map map = new HashMap(); // Поле типа карты } syntax="proto3"; сообщение пользователя { int64 uid = 1; имя строки = 2; карта карта = 3; } Тест:
публичный класс Test { public static void main(String[] args) выдает InvalidProtocolBufferException { Пользователь пользователя = новый пользователь(); user.setUid(1); user.setName("s"); Map map = new HashMap(); карта.пут(1L, 1); user.setMap(карта); Схема Schema = RuntimeSchema.getSchema(User.class); byte[] bytes = ProtobufIOUtil.toByteArray(пользователь, схема, LinkedBuffer.allocate()); System.out.println(Arrays.toString(байты)); UserOuterClass.User pbUser = UserOuterClass.User.newBuilder() .setUid(1) .setName("s") .putMap(1, 1) .строить(); System.out.println(Arrays.toString(pbUser.toByteArray())); UserOuterClass.User newPbUser = UserOuterClass.User.parseFrom(байты); System.out.println(newPbUser.toString()); } } Вывод на консоль:
[8, 1, 18, 1, 115, 26, 6, 10, 4, 8, 1, 16, 1] [8, 1, 18, 1, 115, 26, 4, 8, 1, 16, 1] пользовательский идентификатор: 1 имя: "с" карта { ключ: 0 значение: 0 } Зависимости:
io.protostuff ядро прототипа 1.7.4 io.protostuff среда выполнения прототипа 1.7.4 io.protostuff protostuff-runtime-register 1.7.4 com.google.protobuf protobuf-java 3.21.8 Байты, сгенерированные с помощью ProtobufIOUtil.toByteArray() в ProtoStuff, отличаются от байтов, сгенерированных в ProtoBuf, когда-то с полями типа Map в классе Pojo.
Структура данных карты, закодированная protobuf, примерно такая: fieldTag, eleLen, eleData, fieldTag, eleLen, eleData.
Байтовые данные, преобразованные из protostuff в protobuf, примерно имеют вид fieldTag, fieldLen, fieldTag, eleLen, eleData, fieldTag, eleLen, eleData.
По сравнению с protobuf здесь есть еще две точки данных: fieldTag, fieldLen.
В любом случае, я хочу, чтобы байты, сгенерированные protostuff, анализировались в protobuf для создания того же объекта, что и исходный объект.
Существует ли какая-либо соответствующая конфигурация для прототипов, которая поддерживает отсутствие написания fieldTag и fieldLen в начале?
Если нет, поддерживает ли protostuff пользовательское кодирование и декодирование (я знаю, что Delegate можно использовать для настройки кодирования и декодирования, но, похоже, это требует написания самостоятельно. Я хочу совместить его с исходным кодированием и декодированием карты, но пока не нашел реализации).
---ОБНОВЛЕНИЕ---
Теперь я решил использовать делегат:
публичный класс MapDelegate { public static Final Delegate MAP_INT_LONG_DELEGATE = новый Delegate() { @Override общественный WireFormat.FieldType getFieldType() { вернуть WireFormat.FieldType.MESSAGE; } @Override public Map readFrom(Input input) выдает IOException { // будет реализовано } @Override public void writeTo (Выходной вывод, число int, значение Map, логическое повторение) выдает IOException { // будет реализовано } @Override public void Transfer (трубопровод, входной ввод, выходной вывод, число int, повторение логического значения) выдает IOException { throw new UnsupportedOperationException("Операция передачи не поддерживается."); } @Override общественный класс typeClass() { вернуть Map.класс; } }; } Обновленный Тест:
публичный класс Test { public static void main(String[] args) выдает InvalidProtocolBufferException { Стратегия DefaultIdStrategy = (DefaultIdStrategy) RuntimeEnv.ID_STRATEGY; Strategy.registerDelegate(MAP_INT_LONG_DELEGATE); ... } } Но понятия не имею, как реализовать readFrom и writeTo.
Мобильная версия