不管是XML还是Json还是Google Protobuf都是需要去规定格式的,固定的格式才能去好好的解析出来,双方都可以知道这个代表的意义,毕竟这个经过序列化后的二进制文件将进行多语言之间的通信,必须保持一致性,不然怎么沟通。
option java_package = "com.test.proto";//包的名称
option java_outer_classname = "Person";//生成的数据访问类的类名
option java_package = "com.test.proto";//包的名称
option java_outer_classname = "PersonEntity";//生成的数据访问类的类名
message Person {
required int32 id = 1;//同上
required string name = 2;//必须字段,在后面的使用中必须为该段设置值
optional string email = 3;//可选字段,在后面的使用中可以自由决定是否为该字段设置值
}
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
optional:表示该段为可选值,可以不进行设置。如果不设置,会设置一个默认值。可以设置一个默认值,正如示例中的type字段。否则使用系统默认值,数字类型默认为0;字符串类型默认为空字符串;逻辑类型默认为false;内部自定义的message,默认值通常是message的实例或原型。
repeated:表示该字段可以重复,可出现任意次的, 字段限定标识
注意:使用required字段一定要小心,因为该字段是永久性的。如果以后因为某种原因,想不用该字段,或者要将该字段改成optional或者repeated,那么使用旧接口读取新的协议时,如果发现没有该字段,他们会认为该字段是不完整的,会拒接接收该消息,或者直接丢弃。
tag:每个元素上的“= 1”、“= 2”标记标识二进制编码中字段所使用的唯一“标记”。 numbers 1-15 require one less byte to encode than higher numbers, so as an optimization you can decide to use those tags for the commonly used or repeated elements, leaving tags 16 and higher for less-commonly used optional elements. Each element in a repeated field requires re-encoding the tag number, so repeated fields are particularly good candidates for this optimization.(这个估计是一种优化吧)
protoc -I=.proto文件所在的路径 --java_out=输出的java文件的路径 需要生成的文件的位置addressbook.proto(可以跟着一长串)
E:\Demo\google-proto>protoc.exe -I=E:\Demo\google-proto --java_out=E:\Demo\googl
e-proto E:\Demo\google-proto\person.proto
option java_package ="test.proto";//包的名称
option java_outer_classname ="PersonEntity";//生成的数据访问类的类名
message Person {
required int32 id = 1;//同上
required string name = 2;//必须字段,在后面的使用中必须为该段设置值
optional string email = 3;//可选字段,在后面的使用中可以自由决定是否为该字段设置值
}
package test.proto;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
/**
* Created by wangji on 2017/3/30.
*/
@Slf4j
public class Test {
public static void main(String[] args) {
PersonEntity.Person.Builder builder = PersonEntity.Person.newBuilder();
builder.setName("nnn").setId(1).setEmail("dddd");
PersonEntity.Person person = builder.build();
log.info(person.toString());
for(byte b : person.toByteArray()){
System.out.print(b);
}
log.info(person.toByteString().toString());
try {
//模拟接收Byte[],反序列化成Person类
byte[] byteArray =person.toByteArray();
PersonEntity.Person p2 = PersonEntity.Person.parseFrom(byteArray);
log.info("after :" +p2.toString());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
}
INFO [main] (Test.java:15) - id: 1
name: "nnn"
email: "dddd"
81183110110110264100100100100 INFO [main] <ByteString@61dc03ce size=13>
INFO [main] (Test.java:24) - after :id: 1
name: "nnn"
email: "dddd"
还可以转换为json可以去 https://github.com/bivas/protobuf-java-format