假设大家对protobuf有一些基础,没有用过也没有关系
这里使用protobuf 3.5.0
syntax = "proto3";
package tutorial;
option java_package = "com.spy.test.protobuf.model";
option java_outer_classname = "UserV3Proto";
// User domain comment
/* user domain comment*/
message User{
int64 user_id = 1;
string user_code = 2;
string user_name =3;
string email =4;
int32 age = 5;
repeated string roles = 6;
map<string, string> address=7;
}
protoc userV3.proto --java_out=./
UserV3Proto.User user = UserV3Proto.User.newBuilder()
.setUserId(2L)
.setUserCode("00001")
.setUserName("cc")
.setAge(20)
.addRoles("admin")
.addRoles("cc")
.putAddress("a", "1")
.putAddress("b", "2")
.build();
byte[] bytes = user.toByteArray();
log.debug("{}", bytes);
log.debug("{}", bytes.length);
// 反序列化
UserV3Proto.User user2 = UserV3Proto.User.parseFrom(bytes);
log.debug("{}", user2.toString());
[8, 2, 18, 5, 48, 48, 48, 48, 49, 26, 2, 99, 99, 40, 20, 50, 5, 97, 100, 109, 105, 110, 50, 2, 99, 99, 58, 6, 10, 1, 97, 18, 1, 49, 58, 6, 10, 1, 98, 18, 1, 50]
下面就对这些码流进行分析,逐步拆解到每个字段
通过上面的流程,发现写一个TAG
,这个值是字段序号(fieldNumber
)左移3位,再或
上字段类型,得值8,再将值2输出,即:
user_id: 8, 2,
同样,先写了一个TAG
,其值为(2<<3|2)=18,然后输出string,即:
user_code: 18, 5, 48, 48, 48, 48, 49,
这里以role为例
其实这里的数组role,就是循环输出了String,这里不做过多说明,即:
role: 50, 5, 97, 100, 109, 105, 110,
role: 50, 2, 99, 99,
这里开始输出map中的具体内容
先输出了key和value的序列化总大小,6
将key和value内容序列化输出,类型索引(key或value)大小+长度大小+具体内容
即:
- address 58, 6, 10, 1, 97, 18, 1, 49,
- address 58, 6, 10, 1, 98, 18, 1, 50
总结:
- user_id: 8, 2,
- user_code: 18, 5, 48, 48, 48, 48, 49,
- user_name: 26, 2, 99, 99,
- age: 40, 20,
- role: 50, 5, 97, 100, 109, 105, 110,
- role: 50, 2, 99, 99,
- address: 58, 6, 10, 1, 97, 18, 1, 49,
- address: 58, 6, 10, 1, 98, 18, 1, 50
通过上述截图,可以直观看到根据TAG
即可识别到具体的那个field
,然后赋值。
全篇完。