欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Protobuf動態(tài)解析在Java中的應(yīng)用 包含例子程序

 更新時間:2017年07月24日 08:32:41   投稿:jingxian  
下面小編就為大家?guī)硪黄赑rotobuf動態(tài)解析在Java中的應(yīng)用 包含例子程序。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

最近在做ProtoBuf相關(guān)的項目,其中用到了動態(tài)解析,網(wǎng)上看了下相關(guān)資料和博文都比較少,自己來寫一個記錄一下學(xué)習(xí)過程。

Protocol Buffers是結(jié)構(gòu)化數(shù)據(jù)格式標(biāo)準(zhǔn),提供序列化和反序列方法,用于存儲和交換。語言中立,平臺無關(guān)、可擴展。目前官方提供了C++、Java、Python API,也有其他語言的開源api(比如php)??赏ㄟ^ .proto文件生成對應(yīng)語言的類代碼
如果已知protobuf內(nèi)容對應(yīng)的是哪個類對象,則可以直接使用反序列化方法搞定(Xxx.parseFrom(inputStream)由二進制轉(zhuǎn)換,TextFormat.merge(string, xxxBuilder)由文本轉(zhuǎn)換)

而我們經(jīng)常遇到的情況是,拿到一個被protobuf序列化的二進制內(nèi)容,但不知道它的類型,無法獲得對應(yīng)的類對象。這種多見于需要處理各種各樣未知的ProtoBuf對象的系統(tǒng)。ProtoBuf提供了動態(tài)解析機制來解決這個問題,它要求提供二進制內(nèi)容的基礎(chǔ)上,再提供對應(yīng)類的Descriptor對象,在解析時通過DynamicMessage類的成員方法來獲得對象結(jié)果。
最后問題就是Descriptor對象從哪里來?這是通過protoc --descriptor_set_out=$outputpath 命令生成descriptor文件,進而得到的。

代碼如下:

 cinema.proto

option java_package="com.liulei.cinema";

enum MovieType{
 CHILDREN=1;
 ADULT=2;
 NORMAL=3;
 OHTER=4;
}

enum Gender{
 MAN=1;
 WOMAN=2;
 OTHER=3;
}

message Movie{
 required string name=1;
 required MovieType type=2;
 optional int32 releaseTimeStamp=3;
 optional string description=4;
}

message Customer{
 required string name=1;
 optional Gender gender=2;
 optional int32 birthdayTimeStamp=3;
}

message Ticket{
 required int32 id=1;
 required Movie movie=2;
 required Customer customer=3;
}

Main.java

public static void main( String[] args ) {

  Cinema.Movie.Builder movieBuilder = Cinema.Movie.newBuilder();
  movieBuilder.setName("The Shining");
  movieBuilder.setType(Cinema.MovieType.ADULT);
  movieBuilder.setReleaseTimeStamp(327859200);

  System.out.println("Dynamic Message Parse by proto file");
  try {
   byte[] buffer3 = new byte[movieBuilder.build().getSerializedSize()];
   CodedOutputStream codedOutputStream3 = CodedOutputStream.newInstance(buffer3);
   try {
    movieBuilder.build().writeTo(codedOutputStream3);
    System.out.println(buffer3);
   } catch (IOException e) {
    e.printStackTrace();
   }
   String protocCMD = "protoc --descriptor_set_out=cinema.description ./cinema.proto --proto_path=.";
   Process process = Runtime.getRuntime().exec(protocCMD);
   process.waitFor();
   int exitValue = process.exitValue();
   if (exitValue != 0) {
    System.out.println("protoc execute failed");
    return;
   }
   Descriptors.Descriptor pbDescritpor = null;
   DescriptorProtos.FileDescriptorSet descriptorSet = DescriptorProtos.FileDescriptorSet.parseFrom(new FileInputStream("./cinema.description"));
   for (DescriptorProtos.FileDescriptorProto fdp : descriptorSet.getFileList()) {
    Descriptors.FileDescriptor fileDescriptor = Descriptors.FileDescriptor.buildFrom(fdp, new Descriptors.FileDescriptor[]{});
    for (Descriptors.Descriptor descriptor : fileDescriptor.getMessageTypes()) {
     if (descriptor.getName().equals("Movie")) {
      System.out.println("Movie descriptor found");
      pbDescritpor = descriptor;
      break;
     }
    }
   }
   if (pbDescritpor == null) {
    System.out.println("No matched descriptor");
    return;
   }
   DynamicMessage.Builder pbBuilder = DynamicMessage.newBuilder(pbDescritpor);

   Message pbMessage = pbBuilder.mergeFrom(buffer3).build();
   System.out.println(pbMessage);

  } catch (Exception e) {
   System.out.println("Exception");
   e.printStackTrace();
  }
 }

執(zhí)行結(jié)果:

Dynamic Message Parse From byte array
[B@597ccf6e
Movie descriptor found
name: "The Shining"
type: ADULT
releaseTimeStamp: 327859200

 解釋具體過程:

0.首先對.proto文件使用protoc命令,生成的descriptor文件中包含多個類對應(yīng)的descriptor類信息(序列化的DescriptorSet內(nèi)容)

1.首先取出序列化的DescriptorSet內(nèi)容,F(xiàn)ileDescriptorSet.parseFrom方法反序列化得到FileDescriptorSet對象

2.取出對應(yīng)message類型的Descriptor。

 DescriptorSet成員方法getFileList(),拿到多個FileDescriptorProto對象,再構(gòu)建對應(yīng)FileDescriptor。
 FileDescriptor的成員方法getMessageTypes()得到所有Message的Descriptor對象,找到對應(yīng)名字的Descriptor

3.用Descriptor對象反序列化對象

構(gòu)建DynamicMessage.Builder對象builder,再調(diào)用builder的mergeFrom/merge方法得到Message對象

其中Descriptor相關(guān)類:

DescriptorProtos.DescriptorSet:protoc編譯出來類文件中包含這個類,描述多個.proto文件中的類

DescriptorProtos.FileDescriptorProto:描述一個完整的.proto文件中的類

DescriptorProtos.FileDescriptor:由DescriptorProtos.FileDescriptorProto構(gòu)建而來(buildFrom),描述1個完整.proto文件中的所有內(nèi)容,包括message類型的Descriptor和其他被導(dǎo)入文件的Descriptor。

getMessageTypes()方法:返回List<Descriptors.Descriptor>。得到FileDescriptor內(nèi),所有message類型直接兒子的Descriptor列表   

DescriptorProtos.Descriptor:描述一個message類型,通過getName()得到message的類名

以上這篇基于Protobuf動態(tài)解析在Java中的應(yīng)用 包含例子程序就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java游戲開發(fā)拼圖游戲經(jīng)典版

    Java游戲開發(fā)拼圖游戲經(jīng)典版

    這篇文章主要介紹了Java游戲開發(fā)拼圖游戲經(jīng)典版,對這方面感興趣的同學(xué)可以跟著教程試下
    2021-01-01
  • Java死鎖代碼實例及產(chǎn)生死鎖必備的四個條件

    Java死鎖代碼實例及產(chǎn)生死鎖必備的四個條件

    這篇文章主要介紹了Java死鎖代碼實例及產(chǎn)生死鎖必備的四個條件,Java 發(fā)生死鎖的根本原因是,在申請鎖時發(fā)生了交叉閉環(huán)申請,synchronized在開發(fā)中最好不要嵌套使用,容易導(dǎo)致死鎖,需要的朋友可以參考下
    2024-01-01
  • springboot 整合 sa-token簡介及入門教程

    springboot 整合 sa-token簡介及入門教程

    Sa-Token 是一個輕量級 Java 權(quán)限認(rèn)證框架,主要解決:登錄認(rèn)證、權(quán)限認(rèn)證、Session會話、單點登錄、OAuth2.0、微服務(wù)網(wǎng)關(guān)鑒權(quán) 等一系列權(quán)限相關(guān)問題,這篇文章主要介紹了springboot 整合 sa-token簡介及入門教程,需要的朋友可以參考下
    2023-05-05
  • 如何將Java對象轉(zhuǎn)換為JSON實例詳解

    如何將Java對象轉(zhuǎn)換為JSON實例詳解

    有時候需要將對象轉(zhuǎn)換為JSON格式,所以這篇文章主要給大家介紹了關(guān)于如何將Java對象轉(zhuǎn)換為JSON的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Spring整合MyBatis的三種方式

    Spring整合MyBatis的三種方式

    這篇文章主要介紹了Spring整合MyBatis的三種方式,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Java實現(xiàn)簡單推箱子游戲

    Java實現(xiàn)簡單推箱子游戲

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)推箱子游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • HttpMessageConverter報文信息轉(zhuǎn)換器的深入講解

    HttpMessageConverter報文信息轉(zhuǎn)換器的深入講解

    在Spring中內(nèi)置了大量的HttpMessageConverter,通過請求頭信息中的MIME類型,選擇相應(yīng)的HttpMessageConverter,這篇文章主要給大家介紹了關(guān)于HttpMessageConverter報文信息轉(zhuǎn)換器的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • springboot?jpa之返回表中部分字段的處理詳解

    springboot?jpa之返回表中部分字段的處理詳解

    這篇文章主要介紹了springboot?jpa之返回表中部分字段的處理詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Spring boot + LayIM + t-io 實現(xiàn)文件上傳、 監(jiān)聽用戶狀態(tài)的實例代碼

    Spring boot + LayIM + t-io 實現(xiàn)文件上傳、 監(jiān)聽用戶狀態(tài)的實例代碼

    這篇文章主要介紹了Spring boot + LayIM + t-io 實現(xiàn)文件上傳、 監(jiān)聽用戶狀態(tài)的實例代碼,需要的朋友可以參考下
    2017-12-12
  • Java實現(xiàn)一致性Hash算法詳情

    Java實現(xiàn)一致性Hash算法詳情

    這篇文章主要介紹了Java實現(xiàn)一致性Hash算法詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09

最新評論