protobuf 3.5 java使用介紹(一)

網上大多的資料都是老版本的protobuf例子,正好用到了這個技術,我就把protobuf 3.5的使用方法記錄一下,重點寫了使用方法以及注意事項。

proto描述文件的編寫

syntax = "proto3";

message gps_data {
    int64 id = 1;
    string terminalId = 2;
    string dataTime = 3;
    double lon = 4;
    double lat = 5;
    float speed = 6;
    int32 altitude = 7;
    int32 locType = 8;
    int32 gpsStatus = 9;
    float direction = 10;
    int32 satellite = 11;
}

注意:
* 頂部必須申明句法的版本號,如果不申明,則默認是2.0的語法。
* 下面Message節裏面的字段就是業務需要的各個字段了,等號後面的數字是序號,必須指定。在3.5版本中不用指定required、等關鍵字了。
* gps_data 的名稱格式與爲生成的java文件的名稱是有關係的,如果加入了下劃線,則默認生成的是GpsData 這個駝峯格式的名稱。當然你也可以在文件裏自定義java文件的名稱
如下:

option java_outer_classname = "BatteryData";

但是,生成的java代碼中的的builder還是按照默認格式來生成的,所以,建議大家就直接按照默認規則來設計即可。
* 此外,還可以指定改java代碼的包路徑,命令如下:

option java_package = "com.yjgis.test"; 

但是這裏不建議使用這個功能,因爲包路徑會寫入到生成的代碼中,一旦,代碼進行重構的時候,修改起來會很麻煩,還不如直接把包路徑這種功能交給ide來完成

JAVA代碼的生成

  • 生成JAVA模型的命令
    在命令行工具中敲入下面的命令
protoc -I=src/main/resource/proto 
--java_out=src/main/java src/main/resource/proto/protobuf.proto

說明:
-I 後面是proto文件所在的目錄,
–java_out 後面是生成java文件存放地址
最後一行是proto文件的名稱,可以寫絕對地址,也可以直接寫proto文件名稱

生成的代碼如下所示
這裏寫圖片描述
綠色即是上面文件生成的代碼。

在JAVA中如何使用生成的數據模型

把生成的這個java類拷貝到工程,如下圖:
這裏寫圖片描述

主要需要使用的對象就是綠色方框內的,下面,我們來寫一些代碼

  • 測試代碼
    有如下三個功能即可滿足在業務中的需要了,如下:
    • 使用java代碼生成一個數據模型
    • 把模型轉換爲二進制數據流
    • 把二進制數據流轉成java對象

首先在測試工程pom裏增加依賴

pom:

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

JAVA代碼:

import com.google.protobuf.InvalidProtocolBufferException;

public class TestGpsProtobuf {
    public static void main(String[] args) {
        System.out.println("===== 構建一個GPS模型開始 =====");
        GpsData.gps_data.Builder gps_builder = GpsData.gps_data.newBuilder();
        gps_builder.setAltitude(1);
        gps_builder.setDataTime("2017-12-17 16:21:44");
        gps_builder.setGpsStatus(1);
        gps_builder.setLat(39.123);
        gps_builder.setLon(120.112);
        gps_builder.setDirection(30.2F);
        gps_builder.setId(100L);

        GpsData.gps_data gps_data = gps_builder.build();
        System.out.println(gps_data.toString());
        System.out.println("===== 構建GPS模型結束 =====");

        System.out.println("===== gps Byte 開始=====");
        for(byte b : gps_data.toByteArray()){
            System.out.print(b);
        }
        System.out.println("\n" + "bytes長度" + gps_data.toByteString().size());
        System.out.println("===== gps Byte 結束 =====");

        System.out.println("===== 使用gps 反序列化生成對象開始 =====");
        GpsData.gps_data gd = null;
        try {
            gd = GpsData.gps_data.parseFrom(gps_data.toByteArray());
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        System.out.print(gd.toString());
        System.out.println("===== 使用gps 反序列化生成對象結束 =====");

    }
}

運行一下:

Connected to the target VM, address: '127.0.0.1:59012', transport: 'socket'
===== 構建一個GPS模型開始 =====
id: 100
dataTime: "2017-12-17 16:21:44"
lon: 120.112
lat: 39.123
altitude: 1
gpsStatus: 1
direction: 30.2

===== 構建GPS模型結束 =====
===== gps Byte 開始=====
810026195048495545495045495532495458504958525233-707312243794644157-76-56118-66-113676456172185-102-103-1565
bytes長度50
===== gps Byte 結束 =====
===== 使用gps 反序列化生成對象開始 =====
id: 100
dataTime: "2017-12-17 16:21:44"
lon: 120.112
lat: 39.123
altitude: 1
gpsStatus: 1
direction: 30.2
===== 使用gps 反序列化生成對象結束 =====

如何快速的進行json格式化

我們在使用protobuf的時候,有些場景是需要快速把protobuf生成的對象轉成json的,protobuf提供了很方便的方法來實現這個功能。但是這個功能並不包含在覈心包裏,需要依賴protobuf的工具包。
代碼如下:

pom:
<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java-util</artifactId>
    <version>3.5.0</version>
</dependency>

 System.out.println("===== 使用gps 轉成json對象開始 =====");

 String jsonFormatM = "";
 try {
     jsonFormatM = JsonFormat.printer().print(gd);
 } catch (Exception e) {
     e.printStackTrace();
 }

 System.out.println(jsonFormatM.toString());
 System.out.println("json數據大小:" + jsonFormatM.getBytes().length);
 System.out.println("===== 使用gps 轉成json對象結束 =====");

執行結果:

===== 使用gps 轉成json對象開始 =====
{
  "id": "100",
  "dataTime": "2017-12-17 16:21:44",
  "lon": 120.112,
  "lat": 39.123,
  "altitude": 1,
  "gpsStatus": 1,
  "direction": 30.2
}
json數據大小:145
===== 使用gps 轉成json對象結束 =====

可以看到protobuf數據大小是json的1/3,如果數據模型更復雜或者數據量更大,優勢還會更加明顯。

代碼下載地址

問題

上面,我們學會了protobuf在java中的基本用法,那麼思考幾個問題:

  • 通常我們在數據模型中有可能會出現數組格式,而數組裏面是一個其他的模型,這個怎麼來做?
  • 構建數據消息的時候,通常會有一個頭,一個體;根據頭中定義的數據類型不同,體裏面的數據模型也不相同,這個又該怎麼處理。

上面兩個問題,在稍後的文章裏會跟大家分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章