1. 程式人生 > >Protobuf 協議的Java應用sample

Protobuf 協議的Java應用sample

Protobuf協議,全稱:Protocol Buffer
它跟JSON,XML一樣,是一個規定好的資料傳播格式。不過,它的序列化和反序列化的效率太變態了……

來看看幾張圖你就知道它有多變態。
這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述


Protobuf的Java例項

一、 安裝Protobuf

去Protobuf的GitHub下載,解壓。

如果你是Windows環境,則還要下載多一個東西。protobuf-2.5.0-windows.zip

解壓protobuf-2.5.0-windows.zip,把protoc.exe放在Protobuf安裝目錄下的src裡。(其實放哪都可以)

二、 配置環境變數

編輯系統變數Path,新增Protoc.exe的存放目錄。
這裡寫圖片描述

三、 Eclipse新建專案

我使用maven構建protobuf專案,方便引入protobuf-Java-2.5.0.jar依賴。
在專案根目錄建立proto資料夾,存放proto檔案。
這裡寫圖片描述
maven依賴pom.xml

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>2.5.0</version
>
</dependency>

四、編寫.proto檔案

在proto資料夾下編寫person-entity.proto,如下(proto協議的規則點這檢視

option java_outer_classname = "PersonEntity";//生成的資料訪問類的類名  
message Person {  
  required int32 id = 1;//同上  
  required string name = 2;//必須欄位,在後面的使用中必須為該段設定值  
  optional string email = 3;//可選欄位,在後面的使用中可以自由決定是否為該欄位設定值
}

四、使用protoc.exe編譯成java類

有兩種方法:
1. 使用JavaRumtime執行cmd命令
2. 直接開啟cmd執行命令也行。


1. 使用Java Rumtime執行cmd命令

util包下新建GenerareClass類
這裡寫圖片描述

/**
 * protoc.exe
 * @author ganhaibin
 *
 */
public class GenerateClass {
    public static void main(String[] args) {
        String protoFile = "person-entity.proto";//  
        String strCmd = "d:/dev/protobuf-master/src/protoc.exe -I=./proto --java_out=./src/main/java ./proto/"+ protoFile;  
        try {
            Runtime.getRuntime().exec(strCmd);
        } catch (IOException e) {
            e.printStackTrace();
        }//通過執行cmd命令呼叫protoc.exe程式  
    }
}

命令格式如下。

protoc.exe -I=proto的輸入目錄 --java_out=java類輸出目錄 proto的輸入目錄包括包括proto檔案

2. 直接開啟cmd執行命令

這裡寫圖片描述

生成的PersonEntity.java類

這裡寫圖片描述


五、測試

編寫Test類,模擬序列化和反序列化過程。

public class Test {
    public static void main(String[] args) throws IOException {
        //模擬將物件轉成byte[],方便傳輸
        PersonEntity.Person.Builder builder = PersonEntity.Person.newBuilder();
        builder.setId(1);
        builder.setName("ant");
        builder.setEmail("[email protected]");
        PersonEntity.Person person = builder.build();
        System.out.println("before :"+ person.toString());

        System.out.println("===========Person Byte==========");
        for(byte b : person.toByteArray()){
            System.out.print(b);
        }
        System.out.println();
        System.out.println(person.toByteString());
        System.out.println("================================");

        //模擬接收Byte[],反序列化成Person類
        byte[] byteArray =person.toByteArray();
        Person p2 = Person.parseFrom(byteArray);
        System.out.println("after :" +p2.toString());
    }
}

輸出如下
這裡寫圖片描述


定義複雜的proto檔案

// 生成類的包名
option java_package="com.sample.protobuf";
//生成的資料訪問類的類名
option java_outer_classname="ComplexObjectTest";

message ComplexObject{
    optional int32 id = 1;
    optional string name = 2;
    optional string email = 3;
    repeated string sons = 4;
    optional Gender gender = 5;
    repeated Result result = 6; // 新的物件List
}

enum Gender {
  MAN = 0;
  WOMAN = 1;
}

message Result {
  optional string url = 1;
  optional string title = 2;
  repeated string snippets = 3;
}


public class Brootstrap {

    public static void main(String[] args) throws InvalidProtocolBufferException {
        ComplexObject.Builder builder = ComplexObject.newBuilder();
        builder.setId(100);
        builder.setName("name");
        builder.setEmail("email");
        builder.addSons("Son1");
        builder.addSons("Son2");
        builder.setGender(Gender.MAN);
        Result.Builder r = Result.newBuilder();
        r.setTitle("title");
        builder.addResult(r.build());

        ComplexObject cob = builder.build();
        System.out.println("before :" + cob.toString());

        System.out.println("===========ComplexObject Byte==========");
        for (byte b : cob.toByteArray()) {
            System.out.print(b);
        }
        System.out.println();
        System.out.println(cob.toByteString());
        System.out.println("================================");

        byte[] byteArray = cob.toByteArray();
        ComplexObject cob2 = ComplexObject.parseFrom(byteArray);
        System.out.println("after :" + cob2.toString());

    }
}