2016-03-14 10 views
5

Uważam, że mam tablicę bajtów - bajt [], które reprezentują pewien rodzaj serializowanego obiektu protobuf. Czy istnieje jakiś sposób, aby wydrukować go do wyjścia, cośObiekt protobuf drukowania Java nieznanego typu

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

Gdzie jest int 1 pole, 2 i 3 są ciągi i 4 boolen

TextFormat.print wymaga ode mnie, aby zapewnić konkretną Builder obiektu protobuf, którego nie znam.

Odpowiedz

1

jeśli możemy dokonać przy założeniu, że pola są wszystkie typy pierwotne (czyli nie sub-messages), to powinieneś być w stanie pętli wszystkich pól w bardzo prosty sposób -

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"); 
} 

Jestem jednak dość upewnić się, że obiekty protobuf prawidłowo realizować metody toString(), więc myślę, że powinieneś być w stanie po prostu zadzwonić

protoObj.toString() 

uzyskać reprezentację ciąg obiektu protobuf. Aby uzyskać więcej informacji, zapoznać się z: https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/GeneratedMessage.ExtendableMessage#getAllFields%28%29

+0

Nie mam obiektu wiadomości, jak wspomniano powyżej. Mam tablicę bajtową – user12384512

+0

używając biblioteki google protobuf, powinieneś być w stanie skonstruować obiekt tylko z tablicą bajtów. po co sam go analizować, skoro już istnieją biblioteki? –

+0

To oryginalne pytanie nie dotyczyło użycia biblioteki protobuf, chodziło o to, jak wydrukować wiadomość o nieznanym typie. – user12384512

4

określić typ EmptyMessage jak:

message EmptyMessage { 
    // nothing 
} 

teraz przeanalizować swoją wiadomość jako EmptyMessage, a następnie zadzwonić toString() na nim.

Dlaczego to działa? Weź pod uwagę, że jest kompatybilna wstecz, aby dodać pola do typu wiadomości. Po dodaniu pola, a następnie wysłaniu wiadomości za pomocą tego pola do starego programu, który nie był zbudowany ze znajomością pola, pole jest traktowane jako "pole nieznane". Nieznane pola są drukowane jako pary liczb/wartości. Teraz, jeśli zaczynasz od EmptyMessage i dodajesz pola, możesz oczywiście uzyskać inną wiadomość. Dlatego wszystkie typy wiadomości są "kompatybilne wstecz" z EmptyMessage. Dlatego każdą wiadomość można przeanalizować jako EmptyMessage, aby traktować wszystkie pola jako nieznane pola.

+0

Każdy pomysł jak to zrobić bez zadeklarowania pustych wiadomości w proto? Mam na myśli dynamicznie w Runtime? – user12384512

+0

@ user12384512 Przepraszam, nie rozumiem. To samo 'EmptyMessage' będzie działać dla wszystkich typów, więc dlaczego miałbyś go zdefiniować" dynamicznie w czasie wykonywania "? Dlaczego nie możesz zdefiniować 'EmptyMessage' w tym samym czasie, gdy piszesz inny kod dla tej funkcji? To powiedziawszy, jeśli naprawdę nalegasz na zrobienie tego "dynamicznie w czasie wykonywania", możesz użyć 'DynamicMessage' - ale to będzie znacznie więcej pracy i nie będzie miało żadnych zalet. –

+0

Zastrzeżenie: jeśli protobuf reprezentuje wiadomość zawierającą pod-wiadomość, pod-wiadomość zostanie uszeregowana jako tablica bajtów; innymi słowy, podkomunikat nie będzie nieprywalizowany. – user100464

Powiązane problemy