2015-02-16 82 views
17

GUI ve sunucu arasında protobuf tabanlı iletişim protokolünü kullanan mevcut bir sistemim var. Şimdi biraz sebat eklemek istiyorum, ancak şu anda protobuf mesajları düz bir şekilde üçüncü şahıslara ait özel nesnelere dönüştürülüyor.Java: JSON -> Protobuf & geri dönüşümü

sonra veritabanına kalıcı olabilir json e proto mesajları dönüştürmek için bir yolu var mı.

N.B .: Veritabanı için ikili protobuf yazmak gibi bir fikri sevmiyorum, çünkü bir gün daha yeni sürümlerle geriye dönük uyumlu olmaz ve sistemi bu şekilde kırabilir. Şu anda web API üzerinden göndermek için bir JSON biçime bizim Protobuf mesajları (Message ait şey alt sınıfı) dönüştürmek için protobuf-java-format kullanıyor

+1

"? Peki, JSON'un geriye dönük olarak uyum sağlamasının daha olası olacağını düşünür? Proto şemanızın yeni sürümlerinden mi yoksa genel olarak protokol arabelleklerinin daha yeni sürümlerinden mi bahsediyorsunuz? Benim deneyimim protokol arabellekleri depolamak kesinlikle iyi ... –

+1

Protokol Tamponlar 3 (şu anda beta) doğrudan JSON destekleyecek unutmayın. –

+0

Ayrıca bkz. Https://stackoverflow.com/questions/2544580/is-there-a-standard-mapping-between-json-and-protocol-buffers – Raedwald

cevap

22

.

Basitçe yapın:

JsonFormat.printToString(protoMessage) 
+0

Bu çok yararlıdır. JSON dökümünü protokol arabelleğine dönüştürmek için API'yi paylaşmanız da yararlı olacaktır. – vanguard69

+0

Bu kütüphane, Google Code arşivlerinde olduğu gibi, ÖteHub'a dışa aktarılmadığı için önemli gibi görünüyor. Önemli sorunlar hala açıkken –

+1

@LouisCAD evet, ancak şu anda https://developers.google.com/protocol-buffers/docs/reference adresinde olduğunu düşünüyorum/java/com/google/protobuf/util/JsonFormat – helt

23

Ben bir gün yeni sürümleriyle geriye dönük olarak uyumlu değil olabilir, çünkü çok veritabanına ikili Protobuf yazma bir fikir gibi değil ve bu şekilde sistemi kırmak .

yüke Protobuf geri sonra depolama için JSON Protobuf dönüştürme ve çok olduğu için, uyumluluk sıkıntı yaratabileceği daha: dönüşümü gerçekleştiren süreç ile inşa değilse

  • protobuf şemasının en son sürümü, daha sonra dönüştürme işlemi, sürecin bilmediği alanları sessizce bırakır. Bu, hem depolama hem de yükleme uçları için geçerlidir.
  • En yeni şemada bile, JSON < -> Protobuf dönüşümü, kayan noktalı değerlerin ve benzeri köşe durumlarının varlığında kaybolabilir. Protobuf'lar aslında JSON'dan daha hafif geriye doğru uyumluluk garantilerine sahiptir. JSON'ta olduğu gibi, yeni bir alan eklerseniz, eski istemciler bunu göz ardı eder. JSON'un aksine, Protobufs varsayılan değeri bildirmeye izin verir, bu da yeni istemcilerin alanın eksik olduğu eski verilerle baş etmelerini biraz daha kolaylaştırabilir. Bu sadece hafif bir avantajdır, ancak aksi takdirde Protobuf ve JSON'un eşdeğer geri uyumluluk özellikleri vardır, bu nedenle JSON'da depolamaktan kaynaklanan geriye dönük uyumluluk avantajları elde edemezsiniz. Bütün söyledi

, birçok kütüphane genellikle Protobuf yansıma arayüzünde inşa JSON'dan için protobufs dönüştürmek için orada vardır (Java yansıma arayüzü ile karıştırılmamalıdır; Protobuf yansıması com.google.protobuf.Message arayüzü tarafından sunulan) .

6

Ophir s yanıta ekleme, JsonFormat bile önce protobuf 3,0 mevcuttur. Ancak, bunu yapmanın yolu biraz farklıdır. Protobuf 3'te

.0+, JsonFormat sınıf bir tekil ve bu nedenle, aşağıda İşte

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

Ben kullanır yazdım bir tutorial bağlantısıdır çalışması gerekir aşağıda

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

Protobuf 2.5 + yılında böyle bir şey yapmak bir GsonBuilder nesnesine kaydedilebilen bir TypeAdapter'deki JsonFormat sınıfı. Daha sonra, protokol verilerini Java'ya ve tekrar dönüştürmek için Gson'dan Json ve json yöntemlerini kullanabilirsiniz.

jean. Bir dosyada protobuf verisi varsa ve bir protobuf mesaj nesnesine ayrıştırmak istiyorsanız, TextFormat sınıfını birleştirme yöntemini kullanın. aşağıdaki pasajı bakınız:

// 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(); 
+1

Ve bu PROT için JSON içinde 3,0+: 'JsonFormat.printer(). Print (MessageOrBuilder)' –

1

JsonFormat.printer().print(MessageOrBuilder) deneyin, bu proto3 için iyi görünüyor. Yine de, gerçek bir protobuf iletisinin (.proto dosyasında tanımlı olan java paketi olarak sağlanan) bir com.google.protbuf.Message nesnesine nasıl dönüştürüleceği açık değildir. protobuf 2.5 için

2

, bağımlılık kullanın:

"com.googlecode.protobuf-java-format" % "protobuf-java-format" % "1.2" 

Sonra kodu kullanın:

com.googlecode.protobuf.format.JsonFormat.merge(json, builder) 
com.googlecode.protobuf.format.JsonFormat.printToString(proto) 
bir gün yeni sürümleriyle geriye dönük olarak uyumlu değil olabilir, çünkü tam olarak" demek istiyorsunuz ne