Java: JSON - > Protobuf & back conversion

j'ai un système existant, qui utilise protobuf-fonction protocole de communication entre GUI et server. Maintenant je voudrais ajouter un peu de persistance, mais pour le moment les messages protobuf sont directement convertis en objets personnalisés de tiers.

Est-il un moyen de convertir proto messages json, qui pourrait alors être conservées dans la base de données.

N.B.: je n'aime pas beaucoup l'idée de l'écriture binaire protobuf à la base de données, parce qu'il peut Un jour devenir non rétrocompatible avec les nouvelles versions et briser le système de cette façon.

24
demandé sur Denis Kulagin 2015-02-16 18:58:19
la source

6 ответов

nous utilisons actuellement protobuf-java-format pour convertir nos messages Protobuf (n'importe quelle sous-classe de Message) dans un format JSON pour envoyer notre API web.

il suffit de faire:

  JsonFormat.printToString(protoMessage)
29
répondu jas_raj 2015-02-16 19:42:06
la source

Je n'aime pas beaucoup une idée d'écrire protobuf binaire à base de données, parce qu'il peut Un jour devenir non rétrocompatible avec les nouvelles versions et briser le système de cette façon.

plus susceptible de créer des problèmes de compatibilité, parce que:

  • si le processus qui exécute la conversion n'est pas construit avec la dernière version du protobuf schema, puis conversion laissera tomber en silence tous les champs que le processus ne connaît pas. Ceci est vrai à la fois des fins de stockage et de chargement.
  • même avec le schéma le plus récent disponible, la conversion JSON <-> Protobuf peut être perdue en présence de valeurs floating-point imprécises et de cas de coin similaires.
  • les Protobufs ont en fait (légèrement) plus de garanties de rétrocompatibilité que JSON. Comme avec JSON, si vous ajoutez un nouveau champ, les anciens clients l'ignoreront. Contrairement à JSON, Protobufs permet de déclarer une valeur par défaut, ce qui peut rendre un peu plus facile pour les nouveaux clients de traiter de vieilles données qui manquent autrement le champ. Ce n'est qu'un petit avantage, mais sinon Protobuf et JSON ont des propriétés de rétrocompatibilité équivalentes, donc vous ne gagnez aucun avantage de rétrocompatibilité en stockant dans JSON.

avec tout ce qui est dit, il y a beaucoup de bibliothèques là-bas pour convertir protobufs en JSON, habituellement construit sur L'interface de réflexion de Protobuf (à ne pas confondre avec L'interface de réflexion de Java; la réflexion de Protobuf est offerte par com.google.protobuf.Message interface).

26
répondu Kenton Varda 2015-02-17 08:06:44
la source

Comme indiqué dans le une réponse à une question similaire, car v3.1.0 c'est une fonctionnalité supportée par ProtocolBuffers. Pour Java, inclure le module d'extension com.Google.protobuf: protobuf-java-util et utiliser JsonFormat comme ceci:

JsonFormat.parser().ignoringUnknownFields().merge(json, yourObjectBuilder);
YourObject value = yourObjectBuilder.build();
18
répondu Ophir Radnitz 2017-05-23 14:46:38
la source

ajouter à Ophir S réponse, JsonFormat est disponible même avant protobuf 3.0. Cependant, la façon de faire diffère un peu.

Dans Protobuf 3.0+, le JsonFormat classe est un singleton, et donc faire quelque chose comme ci-dessous

String jsonString = "";
JsonFormat.parser().ignoringUnknownFields().merge(json,yourObjectBuilder);

Dans Protobuf 2.5+, ci-dessous devrait fonctionner

String jsonString = "";
JsonFormat jsonFormat = new JsonFormat();
jsonString = jsonFormat.printToString(yourProtobufMessage);

Voici un lien vers un tutoriel j'ai écrit que j'utilise la classe JsonFormat dans un chapitre de typographie qui peut être enregistré à un GsonBuilder objet. Vous pouvez ensuite utiliser les méthodes toJson et fromJson de Gson pour convertir les données proto en Java et vice versa.

Répondre jean . Si nous avons les données protobuf dans un fichier et que nous voulons les analyser dans un objet de message protobuf, utilisez la méthode de fusion TextFormat classe. Voir ci-dessous l'extrait de code:

// Let your proto text data be in a file MessageDataAsProto.prototxt
// Read it into string  
String protoDataAsString = FileUtils.readFileToString(new File("MessageDataAsProto.prototxt"));

// Create an object of the message builder
MyMessage.Builder myMsgBuilder = MyMessage.newBuilder();

// Use text format to parse the data into the message builder
TextFormat.merge(protoDataAsString, ExtensionRegistry.getEmptyRegistry(), myMsgBuilder);

// Build the message and return
return myMsgBuilder.build();
7
répondu Moses 2017-09-08 14:36:44
la source

JsonFormat.printer().print(MessageOrBuilder), il semble bon pour proto3. Pourtant, il n'est pas clair comment convertir le réel protobuf message (qui est fourni comme le paquet java de mon choix défini dans le .proto file) vers un com.Google.protbuf.Objet du Message.

2
répondu jean 2017-08-25 08:58:35
la source
"com.googlecode.protobuf-java-format" % "protobuf-java-format" % "1.2"

alors utilisez le code:

com.googlecode.protobuf.format.JsonFormat.merge(json, builder)
com.googlecode.protobuf.format.JsonFormat.printToString(proto)
2
répondu Henry 2017-10-10 21:07:10
la source