以前只是偶尔听到protobuf这个东西,json用得顺手也没怎么去了解,最近听几个朋友说protobuf比json好多了,新接触的项目也在考虑用protobuf,恩是时候来了解下protobuf了。
protobuf是何方神圣?
protobuf是google的一个开源项目,是一种传输协议格式,一种语言无关、平台无关、扩展性好的用于通信协议、数据存储的结构化数据串行化方法,你甚至可以在无需重新部署程序的情况下更新数据结构。最先开始是google内部用来服务器之间通信传输的,后来良心发现开源了,对我们广大程序员来说是一大福音啊!
ok,开始第一个demo:
1. 首先去https://github.com/google/protobuf/releases下载windows下执行包protoc-xx.xx.xx-win32.zip;
解压到一个英文目录下(一定要英文,不支持中文目录)
2.在pom.xml中引入需要的依赖:
(当然也可以下载对应语言的编译包编译后引入项目,不过推荐直接maven库加载更加方便,具体操作见http://www.cnblogs.com/superbi/p/4368240.html)
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.0.0-beta-1</version>
</dependency>
3.开始准备用于传输的报文格式proto文件,下面写一个简单的person.proto
option java_package = "com.protobufDemo.proto";
option java_outer_classname = "PersonProbuf";
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 phone = 4;
message CountryInfo {
required string name = 1;
required string code = 2;
optional int32 number = 3;
}
}
message AddressBook {
repeated Person person = 1;
}
有如你所见,消息格式很简单,每个消息类型拥有一个或多个特定的数字字段,每个字段拥有一个名字和一个值类型。值类型可以是数字(整数或浮点)、布尔型、字符串、原始字节或者其他ProtocolBuffer类型,还允许数据结构的分级;equired 不可以增加或删除的字段,必须初始化;optional 可选字段,可删除,可以不初始化;repeated 可重复字段, 对应到java文件里,生成的是List。
4.编译proto文件,转换为java对象
将写好的.proto文件放到protoc-xx.xx.xx-win32.zip解压的目录中与protoc.exe同一目录下;
运行cmd命令提示符(窗口键+R键启动运行),进入对应protoc.exe目录,输入命令:
protoc.exe ./person.proto --java_out=./
中间可能会报错,不过不用理会,在对应的文件目录下已经生成了对应的java文件,复制到项目中对应目录就可以了;
5.demo测试protobuf
package com.protobufDemo.acion;
import java.util.List;
import com.google.protobuf.InvalidProtocolBufferException;
import com.protobufDemo.proto.PersonProbuf;
import com.protobufDemo.proto.PersonProbuf.AddressBook;
import com.protobufDemo.proto.PersonProbuf.Person;
import com.protobufDemo.proto.PersonProbuf.Person.PhoneNumber;
public class TestProto {
public static void main(String[] args) {
// TODO Auto-generated method stub
PersonProbuf.Person.Builder builder = PersonProbuf.Person.newBuilder();
builder.setEmail("kkk@email.com");
builder.setId(1);
builder.setName("TestName");
builder.addPhone(PersonProbuf.Person.PhoneNumber.newBuilder().setNumber("131111111")
.setType(PersonProbuf.Person.PhoneType.MOBILE));
builder.addPhone(PersonProbuf.Person.PhoneNumber.newBuilder().setNumber("011111")
.setType(PersonProbuf.Person.PhoneType.HOME));
Person person = builder.build();
byte[] buf = person.toByteArray();
// PersonProbuf.AddressBook.Builder bookBuild = PersonProbuf.AddressBook.newBuilder();
// bookBuild.addPerson(person);
// AddressBook addressBook = bookBuild.build();
// byte[] buf2 = addressBook.toByteArray();
try {
Person person2 = PersonProbuf.Person.parseFrom(buf);
System.out.println(person2.getName() + ", " + person2.getEmail());
List<PhoneNumber> lstPhones = person2.getPhoneList();
for (PhoneNumber phoneNumber : lstPhones) {
System.out.println(phoneNumber.getNumber());
}
// AddressBook addressBook2 = PersonProbuf.AddressBook.parseFrom(buf2);
// List<Person> addressBookList = addressBook2.getPersonList();
// for (Person p : addressBookList) {
// System.out.println(p.getName() + ", " + p.getEmail());
// List<PhoneNumber> lstPhones = p.getPhoneList();
// for (PhoneNumber phoneNumber : lstPhones) {
// System.out.println(phoneNumber.getNumber());
// }
// }
} catch (InvalidProtocolBufferException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(buf);
}
}
好了,到此protobuf的初体验已大功告成了,相信大家对protobuf有了个初步了解,接下来有时间再研究将protobuf融入到项目框架中,进行真实的开发实用。