1、maven依赖:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.5.1</version>
</dependency>
2、下载protobuff工具(进行编译proto文件,生成java文件),下载地址:https://github.com/google/protobuf/releases,选择自己需要的。
windows环境下,下载protoc-3.5.1-win32.zip,如下图
解压,后面用bin目录中有protoc.exe文件编译proto文件,生成java文件
3、定义person.proto文件
syntax = "proto3";
option java_package = "com.java.protobuff";
option java_outer_classname = "PersonFactory";
message Person{
int32 id = 1;
string name = 2;
int32 age = 3;
Addr addr = 4;
}
message Addr{
string contry = 1;
string city = 2;
}
proto文件编写规则参考:
4、然后用命令编译生成java文件,命令如下:
protoc --java_out=D:\eclipse_workspace\protobuff-hl\src\main\java ./person.proto
解释一下:protoc就是bin目录中有protoc.exe文件
--java_out=表示生成的java文件存放的路径
最后的参数./person.proto,表示定义文件
生成的java文件为PersonFactory,这个文件很复杂,在这里就不细讲了,很重要自己必须看一下。
根据协议已经生成好对象的工厂java,后面开始用这个工厂生成符合协议的对象,然后进行序列化和反序列化操作。
5、编码使用protobuff
下面模拟网络socket通信过程中使用protobuff进行序列化和反序列化的场景:
先上一个图,整体看一下:
具体怎么使用在下面两个文件中:
Client.java:
package com.java.protobuff;
import java.net.Socket;
import com.java.protobuff.PersonFactory.Addr;
import com.java.protobuff.PersonFactory.Person;
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1",3030);
Person.Builder person = Person.newBuilder();
Addr.Builder addr = Addr.newBuilder();
addr.setContry("china").setCity("shenzhen");
person.setId(1).setAge(12).setName("ccf");
person.setAddr(addr);
byte[] messageBody = person.build().toByteArray();
int headerLen = 1;
byte[] message = new byte[headerLen+messageBody.length];
message[0] = (byte)messageBody.length;
System.arraycopy(messageBody, 0, message, 1, messageBody.length);
System.out.println("msg len:"+message.length);
socket.getOutputStream().write(message);
}
}
Server.java:
package com.java.protobuff;
import java.net.ServerSocket;
import java.net.Socket;
import com.java.protobuff.PersonFactory.Person;
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket serverSock = new ServerSocket(3030);
while(true){
Socket sock = serverSock.accept();
byte[] msg = new byte[256];
sock.getInputStream().read(msg);
int msgBodyLen = msg[0];
System.out.println("msg body len:"+msgBodyLen);
byte[] msgbody = new byte[msgBodyLen];
System.arraycopy(msg, 1, msgbody, 0, msgBodyLen);
Person person = Person.parseFrom(msgbody);
System.out.println("Receive:");
System.out.println(person);
}
}
}
6、大致说一下protostuf不太好的地方,个人见解,供参考:
1、需要定义proto文件
2、然后需要使用protoc.exe编译定义的proto文件,生成对象的工厂类
3、工厂类比较复杂,使用的时候有点繁琐
最后说明:这篇博文是入门级的,让你体验一下protobuff,了解怎么使用,差不多了就去深入研究细节,全面掌握。