您的位置:首页 > 编程语言 > Go语言

Google protobuf 协议的使用

2012-11-15 16:43 609 查看
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 文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: