Вторая серия Protobuf3 определяет сложные протофайлы

protobuf

определять сложные объекты

Это вторая серия Protobuf3: как определять более сложные объекты в protobuf

прото-файл

В дополнение к определению базовых объектов, таких как string и int (см. соответствующую взаимосвязь между базовой структурой данных protobuf и переменными Java в конце статьи), вы также можете определить более сложные объекты в proto следующим образом: Define List: значение может быть общей переменной, сложными объектами

message ComplexObject {
   repeated string sons = 4; // List列表
   repeated Result result = 6; // 复杂的对象List
}
// 定义一个新的对象
message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}

определить члены перечисления

message ComplexObject {
    ...
    Gender gender = 5; // Enum值
    ...
}
enum Gender {
  MAN = 0;
  WOMAN = 1;
}

Определить любой объект: используется для определения произвольных значений.

message ComplexObject {
   repeated google.protobuf.Any any = 7; // Any对象
}

Определите объект карты: и ключ, и значение могут быть сложными объектами.

message ComplexObject {
   map<string, MapVaule> map = 8; // 定义Map对象
}
// 定义Map的value值
message MapVaule {
  string mapValue = 1;
}

Назначение тегов и имени файла зарезервировано для будущего расширения.

message ComplexObject {

    reserved 12, 15, 9 to 11; // 预留将来使用的Assigning Tags,
    reserved "foo", "bar"; // 预留将来使用的filed name
}

Приведенный выше полный прото-файл

// 如果使用此注释,则使用proto3; 否则使用proto2
syntax = "proto3";

// 引入外部的proto对象
import "google/protobuf/any.proto";

// 生成类的包名
option java_package = "com.hry.spring.proto.complex";
//生成的数据访问类的类名  
option java_outer_classname = "MyComplexObjectEntity";

message ComplexObject {  
    // Message里每个成员变量都有一个唯一的数字标志(   Assigning Tags)
    int32 id = 1;//  singular, 默认值,表示成员只有0个或者1个
    string name = 2;// 
    string email = 3;//
    repeated string sons = 4; // repeated 列表
    Gender gender = 5; // Enum值
    repeated Result result = 6; // 新的对象List
    repeated google.protobuf.Any any = 7; // Any对象
    map<string, MapVaule> map = 8; // 定义Map对象

    // reserved
    reserved 12, 15, 9 to 11; // 预留将来使用的Assigning Tags,
    reserved "foo", "bar"; // 预留将来使用的filed name
} 

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

// 定义一个新的对象
message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}

// 定义Map的value值
message MapVaule {
  string mapValue = 1;
}

Создание классов Java

Для получения подробной информации о том, как создатьПервая демонстрация Java для Protobuf3. См. сгенерированный класс MyComplexObjectEntity.код

контрольная работа

тестовый класс

ComplexObject.Builder builder = ComplexObject.newBuilder();
// 对应proto里: int32 id = 1;
builder.setId(100);  
// 对应proto里:string name = 2;//
builder.setName("name"); 
// 对应proto里:string email = 3;
builder.setEmail("email");
// 对应proto里:repeated string sons = 4; 列表
builder.addSons("Son1");
builder.addSons("Son2");
// 对应proto里:Gender gender = 5; // Enum值
//  builder.setGenderValue(Gender.MAN_VALUE);
builder.setGender(Gender.MAN);
// 对应proto里:repeated Result result = 6; // 新的Result对象List
Result.Builder r = Result.newBuilder();
r.setTitle("title");
builder.addResult(r.build());
// 对应proto里:repeated google.protobuf.Any any = 7; // Any对象
Any.Builder any = Any.newBuilder();
any.setTypeUrl("typeUrl");
builder.addAny(any.build());
// 对应proto里:map<string, MapVaule> map_field = 8;
MapVaule.Builder mapValue = MapVaule.newBuilder();
mapValue.setMapValue("mapValue");
builder.putMap("mapKey", mapValue.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[],反序列化成Person类
byte[] byteArray =cob.toByteArray();
ComplexObject cob2 = ComplexObject.parseFrom(byteArray);
System.out.println("after :" + cob2.toString());

результат

before :id: 100
name: "name"
email: "email"
sons: "Son1"
sons: "Son2"
result {
  title: "title"
}
any {
  type_url: "typeUrl"
}
map {
  key: "mapKey"
  value {
    mapValue: "mapValue"
  }
}

===========ComplexObject Byte==========
810018411097109101265101109971051083448311111049344831111105050718511610511610810158910711612111210185114108662010610997112751011211810108109971128697108117101
<ByteString@1b0375b3 size=69>
================================
after :id: 100
name: "name"
email: "email"
sons: "Son1"
sons: "Son2"
result {
  title: "title"
}
any {
  type_url: "typeUrl"
}
map {
  key: "mapKey"
  value {
    mapValue: "mapValue"
  }
}

Соответствующая связь между базовой структурой данных protobuf и переменными Java

这里写图片描述

код

github