2016-03-14 3 views
5

У меня есть массив байтов - byte [], которые представляют собой своего рода сериализованный объект protobuf. Есть ли способ, чтобы распечатать его для вывода, что-то вродеJava print protobuf объект неизвестного типа

1: 123 
2: Jhon 
3: Doe 
4: 0 

Где 1 является ИНТ поле, 2 и 3 являются строками и 4 boolen

TextFormat.print требует от меня, чтобы обеспечить конкретный Builder объекта protobuf, которого я не знаю.

ответ

1

, если мы можем сделать предположение о том, что поля являются всеми примитивными типами (т.е. не подсообщением), то вы должны быть в состоянии перебрать все поля очень просто -

for(Entry<FieldDescriptor, Object> entry : msg.getAllFields().entrySet()) 
{ 
    if(entry.getValue() != null) 
     System.out.println(entry.getKey().getName() + ": " + entry.getValue().toString()); 
    else 
    System.out.println(entry.getKey().toString() + ": null"); 
} 

Тем не менее, я очень уверен, что Protobuf объекты правильно реализовать метод ToString(), так что я думаю, вы должны быть в состоянии просто позвонить

protoObj.toString() 

, чтобы получить строковое представление объекта Protobuf. Для получения дополнительной информации, посмотрите на: https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/GeneratedMessage.ExtendableMessage#getAllFields%28%29

+0

У меня нет объекта сообщения, как я уже говорил выше. У меня есть байтовый массив – user12384512

+0

, используя библиотеку goob protobuf, вы должны иметь возможность построить объект только с байтовым массивом. зачем разбирать его самостоятельно, когда есть библиотеки, сделанные для этого? –

+0

Этот оригинальный вопрос касался не использования библиотеки protobuf, а о том, как печатать сообщение неизвестного типа. – user12384512

4

Определить тип EmptyMessage как:

message EmptyMessage { 
    // nothing 
} 

Теперь разобрать ваше сообщение как EmptyMessage, а затем вызвать toString() на него.

Почему это работает? Ну, учтите, что он обратно совместим для добавления полей в тип сообщения. Когда вы добавляете поле, затем отправляйте сообщение, используя это поле, в старую программу, которая не строилась со знанием поля, тогда поле рассматривается как «неизвестное поле». Неизвестные поля печатаются как пары число/значение. Теперь, если вы начинаете с EmptyMessage и добавляете поля, вы можете получить любое другое сообщение. Поэтому все типы сообщений «обратно совместимы» с EmptyMessage. Поэтому любое сообщение может быть проанализировано как EmptyMessage для обработки всех полей в виде неизвестных полей.

+0

Любая идея, как это сделать, не объявляя пустой msg в прото? Я имею в виду динамически в Runtime? – user12384512

+0

@ user12384512 Извините, я не понимаю. Тот же 'EmptyMessage' будет работать для всех типов, так зачем вам его динамически определять во время выполнения? Почему вы не можете определить «EmptyMessage» одновременно с написанием другого кода для этой функции? Тем не менее, если вы действительно настаиваете на том, чтобы это «динамически выполнялось во время выполнения», вы можете использовать «DynamicMessage», но это будет больше работать и не будет иметь никаких преимуществ. –

+0

Предостережение: если protobuf представляет сообщение, содержащее под-сообщение, суб-сообщение будет стягиваться как массив байтов; другими словами, под-сообщение не будет неэтериализованным. – user100464

Смежные вопросы