Netty学习——Google Protobuf的初步了解
学习参考的官网: https://developers.google.com/protocol-buffers/docs/javatutorial
简单指南详解:这个文档写的简直是太详细了。
本篇从下面三个步骤进行介绍:
- I. Define message formats in a .proto file.
- II. Use the protocol buffer compiler.
- III. Use the Java protocol buffer API to write and read messages.
详细内容,我就不做过多解释,自行查阅官方文档,在这只是记录,我觉得比较重要的东西,能够帮助我更好的理解。
I.Define message formats in a .proto file.
syntax = "proto2"; package tutorial; //包名 option java_package = "com.example.tutorial"; //针对于java的包名
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]; // optional类型 和定义默认值
} repeated PhoneNumber phones = 4;
} message AddressBook {
repeated Person people = 1; //repeated类型,其实就相当于java的ArrayList,用来
}
其他需要注意的点:
1.对于前两个字段java_package 和 package ,就是说,可以不写java_package,会默认 调用package ,写了java_package,java就会识别这个,但是就算写了java_package,也要package ,是为了其他语言能够有包名能够使用

2.这个数字,=1, =2 ,不是顺序,或者是赋值,只是每一个字段在Proto文件中,都会有一个唯一数字标识符

3.对于以下的三种类型 required,optional,repeated 官方推荐,尽量不是用required,因为弊大于利。

II. Use the protocol buffer compiler.
需要注意的地方:
使用PB编译器生成出的对象是不可变的,需要使用构建器的方法连模式(set.set.set )一个一个的去设置值,然后再需要最后使用build方法去完成整个对象的创建,如下介绍
每一次set完之后的返回结果,都是另一个构建器,就是为了能够在一行代码上,完成对象的构建

通过构建器的方法连模式,完成一个对象的创建和设置值的标准写法:如下
Person john =
Person.newBuilder()
.setId(1234)
.setName("John Doe")
.setEmail("jdoe@example.com")
.addPhones(
Person.PhoneNumber.newBuilder()
.setNumber("555-4321")
.setType(Person.PhoneType.HOME))
.build();
Message除了自定义的属性之外,还提供的有几个默认的方法,让你能够检查和操作整个消息
isInitialized()://检查是否所有的必备字段,都已经被设置值 toString(): //返回一个人类可读的字符形式,通常用于调试 mergeFrom()://(只有构建器才有)将另一个消息的内容,合并到当前消息当中并且覆盖之前的标量字段,合并复核的字段和重复的阻断,完成对象的合并 clear()://(只有构建器才有) 恢复到原来属性都为空的这个状态

解析和序列化这些消息
byte[] toByteArray(); //将消息序列化,并返回了包含原生字节的一个字节数组,就是把消息本身转换成字节数组 static Person parseFrom(byte[] data);//从给定的字节数组当中解析这条消息,将字节数组的内容转换成对象 void writeTo(OutputStream output);//将消息序列化,并输出到一个输出流当中, static Person parseFrom(InputStream input); //接着读取输入流中的消息并进行解析
注意:不能通过继承的方式,给这个对象添加更多的行为。
如果想要给这个message对象赋予响应的方法,可以借助使用多个message合并的方式来实现功能而并不是通过继承的方式

III. Use the Java protocol buffer API to write and read messages.
Writer a Message
import com.example.tutorial.AddressBookProtos.AddressBook;
import com.example.tutorial.AddressBookProtos.Person;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintStream; class AddPerson {
// This function fills in a Person message based on user input.
static Person PromptForAddress(BufferedReader stdin,
PrintStream stdout) throws IOException {
Person.Builder person = Person.newBuilder(); stdout.print("Enter person ID: ");
person.setId(Integer.valueOf(stdin.readLine())); stdout.print("Enter name: ");
person.setName(stdin.readLine()); stdout.print("Enter email address (blank for none): ");
String email = stdin.readLine();
if (email.length() > 0) {
person.setEmail(email);
} while (true) {
stdout.print("Enter a phone number (or leave blank to finish): ");
String number = stdin.readLine();
if (number.length() == 0) {
break;
} Person.PhoneNumber.Builder phoneNumber =
Person.PhoneNumber.newBuilder().setNumber(number); stdout.print("Is this a mobile, home, or work phone? ");
String type = stdin.readLine();
if (type.equals("mobile")) {
phoneNumber.setType(Person.PhoneType.MOBILE);
} else if (type.equals("home")) {
phoneNumber.setType(Person.PhoneType.HOME);
} else if (type.equals("work")) {
phoneNumber.setType(Person.PhoneType.WORK);
} else {
stdout.println("Unknown phone type. Using default.");
} person.addPhones(phoneNumber);
} return person.build();
} // Main function: Reads the entire address book from a file,
// adds one person based on user input, then writes it back out to the same
// file.
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println("Usage: AddPerson ADDRESS_BOOK_FILE");
System.exit(-1);
} AddressBook.Builder addressBook = AddressBook.newBuilder(); // Read the existing address book.
try {
addressBook.mergeFrom(new FileInputStream(args[0]));
} catch (FileNotFoundException e) {
System.out.println(args[0] + ": File not found. Creating a new file.");
} // Add an address.
addressBook.addPerson(
PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
System.out)); // Write the new address book back to disk.
FileOutputStream output = new FileOutputStream(args[0]);
addressBook.build().writeTo(output);
output.close();
}
}
Reader a Message
import com.example.tutorial.AddressBookProtos.AddressBook;
import com.example.tutorial.AddressBookProtos.Person;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream; class ListPeople {
// Iterates though all people in the AddressBook and prints info about them.
static void Print(AddressBook addressBook) {
for (Person person: addressBook.getPeopleList()) {
System.out.println("Person ID: " + person.getId());
System.out.println(" Name: " + person.getName());
if (person.hasEmail()) {
System.out.println(" E-mail address: " + person.getEmail());
} for (Person.PhoneNumber phoneNumber : person.getPhonesList()) {
switch (phoneNumber.getType()) {
case MOBILE:
System.out.print(" Mobile phone #: ");
break;
case HOME:
System.out.print(" Home phone #: ");
break;
case WORK:
System.out.print(" Work phone #: ");
break;
}
System.out.println(phoneNumber.getNumber());
}
}
} // Main function: Reads the entire address book from a file and prints all
// the information inside.
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println("Usage: ListPeople ADDRESS_BOOK_FILE");
System.exit(-1);
} // Read the existing address book.
AddressBook addressBook =
AddressBook.parseFrom(new FileInputStream(args[0])); Print(addressBook);
}
}
Netty学习——Google Protobuf的初步了解的更多相关文章
- Netty学习——Google Protobuf使用方式分析和环境搭建
Google Protobuf使用方式分析 在RPC框架中,Google Protobuf是很常用的一个库,和Apache Thrift 是同款的用于进行序列化的第三方库.原理都是大同小异,无非就是使 ...
- netty 的 Google protobuf 开发
根据上一篇博文 Google Protobuf 使用 Java 版 netty 集成 protobuf 的方法非常简单.代码如下: server package protobuf.server.imp ...
- 《精通并发与Netty》学习笔记(05 - Google Protobuf与Netty的结合)
protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等.其特点是不限语言.不限平台.扩展性强 Netty也提供了对Protobuf的天然支持,我们今天 ...
- 《精通并发与Netty》学习笔记(04 - Google Protobuf介绍)
一 .Google Protobuf 介绍 protobuf是google团队开发的用于高效存储和读取结构化数据的工具,是Google的编解码技术,在业界十分流行,通过代码生成工具可以生成不同语言版本 ...
- Netty学习(七)-Netty编解码技术以及ProtoBuf和Thrift的介绍
在前几节我们学习过处理粘包和拆包的问题,用到了Netty提供的几个解码器对不同情况的问题进行处理.功能很是强大.我们有没有去想这么强大的功能是如何实现的呢?背后又用到了什么技术?这一节我们就来处理这个 ...
- Netty学习——Netty和Protobuf的整合(二)
Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...
- Netty学习——Netty和Protobuf的整合(一)
Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执 ...
- Google Protobuf结合Netty实践
1.Win版Protobuf代码生成工具下载: https://github.com/protocolbuffers/protobuf/releases 注意下载protoc-3.6.1-win32. ...
- Netty使用Google的ProtoBuf
protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等.其特点是不限语言.不限平台.扩展性强 Netty也提供了对Protobuf的天然支持,我们今天 ...
随机推荐
- 洛谷P3121 【[USACO15FEB]审查(黄金)Censoring (Gold)】
双栈+AC自动机 这题其实跟一道KMP算法的题有一些渊源,它就是这道题的简单板. Clear: 给你两个串A,B,每次在B串中从左到右找串A,并将该子串删除,直到找不到为止,问你能删几次. 样例输入: ...
- iOS:探究视图控制器的转场动画
一.介绍 在iOS开发中,转场动画的使用无处不见,不只是我们自己更多的使用UIViewblock动画实现一个转场动画,其实,在我们实现VC控制器跳转的时候都是转场动画的实现,例如标签栏控制器的切换.模 ...
- RocketMQ实战:生产环境中,autoCreateTopicEnable为什么不能设置为true
1.现象 很多网友会问,为什么明明集群中有多台Broker服务器,autoCreateTopicEnable设置为true,表示开启Topic自动创建,但新创建的Topic的路由信息只包含在其中一台B ...
- 让NOI Linux变得可用
开始用NOI Linux-- 上古加阉割,还是32位,完全不可用的亚子-- 怎么办,我真的好想念16.04 于是就走上魔改之旅-- 一些神奇的操作 git 听说直接装的话会是上古版本 sudo add ...
- ORACLE存储过程的创建和执行的简单示例和一些注意点
此示例的主要目的主要是为了了解在PL/SQL环境下怎么创建和执行存储过程. 存储过程所涉及的DataTable: 第一步:创建游标变量 游标是ORACLE系统在内存中开辟的一个工作区,主要用来存储SE ...
- 随机点名小程序--- -JAVA版本
话不多少,直接上代码 一个能够直接运行的随机点名的小程序,一个界面化的小程序.望广大网友多多支持! 1.创建一个随机点名的类 public class ProcessRandomName { JFra ...
- Asp.net Core 系列之--4.事务、日志及错误处理
ChuanGoing 2019-11-17 这篇原本时想把事务处理.日志处理.错误处理.授权于鉴权一并介绍完的,授权和鉴权我想结合自定义权限来介绍,全部放到这里篇幅可能太长,因此权限部分将会在下篇来介 ...
- C# IV: 数据库基础操作2
需上一篇C# III:数据库基础操作 另外一个经常碰到的数据库操作是,单次执行多个SQL语句,譬如,一次性插入多条数据. 方法一,拼凑长SQL语句 拼凑长SQL语句实际上是String的操作.如下示例 ...
- deepin MySQL 安装以及编码格式的修改utf-8
deepin MySQL 安装以及编码格式的修改utf-8: 1.sudo apt-get install mysql-server mysql-client 2.sudo mysql -u root ...
- nyoj 76-超级台阶 (递推)
76-超级台阶 内存限制:64MB 时间限制:1000ms 特判: No 通过数:8 提交数:12 难度:3 题目描述: 有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共 ...