2016-03-14 6 views
5

Si consideri che ho array di byte - byte [] che rappresentano una sorta di oggetto protobuf serializzato. C'è un modo per stampare a uscita, qualcosa comeJava print protobuf oggetto di tipo sconosciuto

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

dove 1 è campo int, 2 e 3 sono stringhe e 4 è boolen

TextFormat.print mi obbliga a fornire calcestruzzo Builder di oggetto protobuf, che non conosco.

risposta

1

se siamo in grado di fare l'ipotesi che i campi sono tutti i tipi primitivi (cioè non sotto-messaggi) allora si dovrebbe essere in grado di scorrere tutti i campi molto semplicemente -

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

Tuttavia, sono abbastanza assicurarsi che gli oggetti protobuf attuare correttamente il metodo toString(), quindi penso che si dovrebbe essere in grado di chiamare semplicemente

protoObj.toString() 

per ottenere una rappresentazione stringa dell'oggetto protobuf. Per ulteriori informazioni, dare un'occhiata a: https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/GeneratedMessage.ExtendableMessage#getAllFields%28%29

+0

Non ho oggetto messaggio come ho menzionato sopra. Ho array di byte – user12384512

+0

utilizzando la libreria google protobuf, dovresti essere in grado di costruire l'oggetto con solo la matrice di byte. perché analizzarlo da solo quando ci sono già delle biblioteche che lo fanno? –

+0

Questa domanda originale non riguardava l'uso della libreria protobuf, ma riguardava la modalità di stampa del messaggio di tipo sconosciuto. – user12384512

4

Definire un tipo EmptyMessage come:

message EmptyMessage { 
    // nothing 
} 

Ora analizzare il messaggio come EmptyMessage, quindi chiamare toString() su di esso.

Perché funziona? Bene, considera che è compatibile con le versioni precedenti per aggiungere campi a un tipo di messaggio. Quando aggiungi un campo, quindi invii un messaggio usando quel campo a un vecchio programma che non è stato creato con la conoscenza del campo, allora il campo viene trattato come "campo sconosciuto". I campi sconosciuti vengono stampati come coppie numero/valore. Ora, se inizi con EmptyMessage e aggiungi campi, puoi ovviamente ottenere qualsiasi altro messaggio. Pertanto, tutti i tipi di messaggio sono "retrocompatibili" con EmptyMessage. Pertanto, qualsiasi messaggio può essere analizzato come EmptyMessage per trattare tutti i campi come campi sconosciuti.

+0

Qualche idea su come farlo senza dichiarare vuoto msg in proto? Intendo in modo dinamico in Runtime? – user12384512

+0

@ user12384512 Mi dispiace, non capisco. Lo stesso 'EmptyMessage' funzionerà per tutti i tipi, quindi perché dovresti definirlo" dinamicamente in runtime "? Perché non puoi definire 'EmptyMessage' nello stesso momento in cui stai scrivendo l'altro codice per questa funzione? Detto questo, se si vuole davvero farlo "dinamicamente in fase di esecuzione", è possibile utilizzare 'DynamicMessage' - ma questo sarà molto più lavoro e non avrà alcun vantaggio. –

+0

Avvertenza: se il protobuf rappresenta un messaggio che contiene un sotto-messaggio, il sotto-messaggio sarà sottoposto a stringa come array di byte; in altre parole, il sotto-messaggio non sarà non serializzato. – user100464