Encoding/decoding is also called serialization/deserialization in Java. The serialization and deserialization technology of Java itself generates too much binary stream and has low conversion efficiency. It is generally not suitable for the encoding framework of remote cross-node calls.
Protobuf, known as Protocol Buffers, comes from Google Open Source with the following characteristics:
- Small bit stream and high efficiency
- Language platform is independent, not only Java, but also C++, python.
- Using data description files, code can be generated automatically
- In contrast to Facebook Thirft, Protobuf does not need to fully define all the structures at the beginning, but can structure before the later extends and still read the information encoded by the previous structure.
Use steps:
- Write. proto class definition file
- Generate corresponding Java classes through the compiler provided
- Read and write information using the provided API
1. Writing. proto Class Definition File
package tutorial; option java_package = "com.example.tutorial"; 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]; } repeated PhoneNumber phones = 4; } message AddressBook { repeated Person people = 1; }
Document description:
- Package is used to distinguish between files of the same name. By default, java_package is the package of the generated bean.
- java_outer_classname specifies the class that contains all the classes defined in the file and automatically sets the. proto file name to the class name by default.
- message defines a class that can contain messages
- The numbers = 1, = 2 after each attribute are "unique identifiers" of the attribute when binarizing data, independently numbered in each message.
Supported modifiers:
- Required: Identify the fields that must be provided, and if the required field value is not provided, an exception will run out when encoding and decoding.
- optional: Identify fields that can be provided or not, and return default values if not. The default values are similar to those in java, but the fields of "sub-message" are all empty. Default values can also be set with [default = value].
- repeated: Identify ArrayList
- Numbers = 1, = 2 after each attribute. Note that 0-15 is one byte less than the subsequent number when it is re-serialized. Gu 0-15 is generally used in required and repeated fields.
Supported data types: bool, int32, float, double, string, enum
2. Generating corresponding Java classes through the compiler provided
2.1. Place protoc.exe and corresponding. proto files in the java folder where the project is located
protoc.exe --java_out=.\ .\Request.proto
You can generate the specified file at the location described by java_package in the proto file above
3. Read and write information using the API provided
public class TestSubscribeReqProto { /** * 1,Building objects * @return */ public static SubscribeReqProto.SubscribeReq createSubscribeReq(){ SubscribeReqProto.SubscribeReq.Builder builder = SubscribeReqProto.SubscribeReq.newBuilder(); builder.setSubReqID(1); builder.setUserName("caizhijie"); builder.setProductName("Yellow Book"); List<String> address = new ArrayList<>(); address.add("NanJing YuHuaTai"); address.add("BeiJing ZhiJinCheng"); address.add("ShenZhen HongShuLin"); builder.addAllAddress(address); return builder.build(); } /** * 2,Code * @param req * @return */ public static byte[] encode(SubscribeReqProto.SubscribeReq req){ return req.toByteArray(); } /** * 3,Decode * @param body * @return * @throws InvalidProtocolBufferException */ public static SubscribeReqProto.SubscribeReq decode(byte[] body) throws InvalidProtocolBufferException { return SubscribeReqProto.SubscribeReq.parseFrom(body); } public static void main(String[] args) throws InvalidProtocolBufferException { SubscribeReqProto.SubscribeReq req = createSubscribeReq(); System.out.println("Before encode : "+req.toString()); SubscribeReqProto.SubscribeReq req2 = decode(encode(req)); System.out.println("After encode : "+req2.toString()); System.out.println("Assert equal : -->" + req2.equals(req)); } }