Google protobuf 是一个高性能的通信协议,具有多语言支持,协议数据小,方便传输,高性能等特点。通过将数据序列化成二进制数组,并将二进制数组反序列化成数据对象。用于取代JSON,XML,作为服务器优秀的通信协议。
本文档的示例用JAVA编写
先去google的网站上下载protobuf 协议的支撑包地址:http://code.google.com/p/protobuf/downloads/list 要下载两个东西一个是 protobuf-2.4.1.zip 支撑包,protoc-2.4.1-win32.zip代码生成工具
稍微讲一下google protobuf的工作流程;首先,编写后缀为.proto的数据格式文件,该文件用来定义数据格式
其次,protobuf的代码生成工具,生成你想要的代码,这里生成JAVA。
能后,调用protobuf生成的类提供的.proto数据结构的解析以及进行.proto数据序列化反序列化的方法,进行数据的二进制序列化以及反序列化
最后,你就可以像使用JSON那样,进行数据的传递了
继续讲怎么用,下载下来包后,把protobuf-2.4.1.zip 包解压,找到JAVA文件夹,将JAVA文件下的src打成jar导入你的项目里(当然你亦可以直接引用不打jar),后面的方法需要调用这个jar的接口
引入项目后,在你项目src跟目录下,编写数据结构文件,这里为User.proto,文件如下
package test;
option java_package = "com.example.test";
option java_outer_classname = "TestUserProtos";
message User{
required int32 id =1;
required string name =2;
required double weight =3;
required double height =4;
required int32 age =5;
}
这是一个简单的数据结构,看起来就更JAVA一样
第一行为包名,可以不管他
option java_package = "com.example.test"; 指定生成的报名
option java_outer_classname = "TestUserProtos"; 指定生成的类名
能后就是数据体了
数据类型bool,int32,float,double和string也可以使用自己定义的类型,类类型,这个下面有
每个字段必须提供一个修饰词:
1、required: 表示字段必须提供,不能为空.否则,message会被认为是未初始化的,识图build为初始化的message会抛出RuntimeException,解析未初始化的message会抛出IOException..除此之外,一个required字段与optional字段完全相同.
2、optional:可选字段,可以设置也可以不设置.如果没有设置,会设置一个缺省值.你可以指定一个缺省值,正像电话号码的type字段,否则,使用系统的缺省值:数字类型缺省为0,字符类型缺省为空串,逻辑类型缺省为false.对于嵌入的message,缺省值通常是message的实例或原型.
3、repeated:字段可以被重复(包括0),可以同于动态大小的数组.
"=1","=2",是编码顺序,不可以相同,总共有“1-15” 官网上用这么一句话来说明Tag numbers 1-15 require one less byte to encode than higher numbers
在来看一个复杂一点的
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2; // Unique ID number for this person.
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 phone = 4;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}
上面除了基本的数据类型以外,还定义了一个PhoneNumber 的类型,PhoneNumber 类型里面,又有一个message数据结构,有两个字段,类型里面又有个枚举类型,另外外层的AddressBook 定义也定义了 Person 结构,这样看是不是和json的数据bean很像呢,里面包含的PhoneNumber 相当于个类的数组
定义好了以后,使用protoc-2.4.1-win32.zip进行代码生成
现在打开命令窗口 进入项目的src目录下
执行命令 protoc --java_out=. addressbook.proto(注意.后面有个空格哦)
也有自己知道目录的,protoc -I=$SRC_DIR --java_out=$DST_DIR addressbook.proto
$DST_DIR:生成的java代码的文件夹
现在就生成了AddressBookProtos.java文件
生成好了后,调用AddressBookProtos.java提供的接口进行数据的序列化,反序列化操作,代码如下
package com.example.tutorial;
import com.example.tutorial.AddressBookProtos.Person;
import com.example.tutorial.AddressBookProtos.Person.PhoneNumber;
import com.example.tutorial.AddressBookProtos.Person.PhoneType;
import com.google.protobuf.InvalidProtocolBufferException;
public class AddPersonTest {
/**
* 序列化
* @return
*/
public static byte[] toModel(){
AddressBookProtos.Person.Builder builder = AddressBookProtos.Person.newBuilder();
builder.setEmail("aaabbb");
builder.setName("张三");
builder.setId(1);
PhoneNumber.Builder num = PhoneNumber.newBuilder();
num.setNumber("123123");
num.setType(PhoneType.WORK);
builder.addPhone(num);
AddressBookProtos.Person model = builder.build();
return model.toByteArray();
}
/**
* 反序列化
* @param data
* @return
*/
public static Person getModel(byte[] data){
AddressBookProtos.Person msg = null;
try {
msg = AddressBookProtos.Person.parseFrom(data);
} catch (InvalidProtocolBufferException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return msg;
}
public static void main(String[] args) {
Person msg = AddPersonTest.getModel(AddPersonTest.toModel());
System.out.println("name:"+msg.getName());
System.out.println("email:"+msg.getEmail());
System.out.println("ID:"+msg.getId());
}
}
可以看到生成的AddressBookProtos.java提供了builder.build();方法生成二进制的Model,提供了parseFrom(data);方法解析二进制的数据到实体类
可以自己看看AddressBookProtos.java,会发现和你之前写的addressbook.proto数据结构是一一对应的
这样,就可以用builder.build();方法生成二进制的Model传递数据了,比JSON小哦,还没有那么多对应的属性名字,传过去之后,另一头也根据addressbook.proto文件生成相应代码去解析就是了,可以生成JAVA的,也可以生成C++的,是不是很好用呢,去试试吧
参考链接:http://xzgf.iteye.com/blog/215986
http://www.cnblogs.com/foxhengxing/archive/2010/08/10/1796165.html
http://my.oschina.net/lxping/blog/54603
本文档面向希望使用protocol buffer的Java、C++或Python开发者。这个概览介绍了protocol buffer,并告诉你如何开始,你随后可以跟随编程指导( http://code.google.com/apis/protocolbuffers/docs/tutorials.html )深入了解protocol buffer编码方式( http://code.google.com/apis/protocolbuffers/docs/encoding.html )。API参考文档( http://code.google.com/apis/protocolbuffers/docs/reference/overview.html )同样也是提供了这三种编程语言的版本,不够协议语言( http://code.google.com/apis/protocolbuffers/docs/proto.html )和样式( http://code.google.com/apis/protocolbuffers/docs/style.html )指导都是编写 .proto 文件。