protobuf learning (3): compile .proto files to generate Java code, and serialize and deserialize messages

Overview

Learning in protobuf (2): Definition of .proto file After learning the definition of .proto file, this chapter introduces how to generate Java code through protoc (protobuf compiler).

Download and installation of protoc

In the protobuf official website Basics:java , find Compiling Your Protocol Buffers , and download the corresponding protoc package according to the instructions . I am windows, and the download is as follows:

Note: The package name of protoc has no language-protoc-3.13.0-win64.zip.

Download protobuf-java-3.13.0.zip too, and it will be useful later.

Unzip protoc-3.13.0-win64.zip to get the following directory:

Configure environment variables:

Path:

Verify the installation:

Enter protoc directly and press Enter:

There are commands to help the configuration succeed.

.proto file definition

Create .proto anywhere in the project . My directory structure is as follows:

Although the proto directory can be created anywhere, the path of the .proto file will affect the subsequent command parameters. At the same time, for the rationality of the project structure, it is recommended to create it like me.

Write a .proto file Student.proto

syntax = "proto2";

package com.leolee.protobuf;

option optimize_for = SPEED;//Can be set to SPEED, CODE_SIZE, or LITE_RUNTIME,This affects the C++ and Java code generators (and possibly third-party generators) in the following ways
option java_package = "com.leolee.protobuf";
option java_outer_classname = "DataInfo";

message Student {

  required string name = 1;

  optional int32 age = 2;

  optional string address = 3;
}
//生成java code 命令:protoc --java_out=src/main/java/ src/protobuf/Student.proto

Pay attention to the definition values of ( java_package = "com.leolee.protobuf"; ) and ( java_outer_classname = "DataInfo"; ), the generated Java code will generate the DataInfo.java class in the com.leolee.protobuf directory of the project .

Use protoc to generate Java code

Enter in the command window:

protoc --java_out=src/main/java/ src/protobuf/Student.proto

The DataInfo.java class will be generated in the corresponding java package soon .

Test the serialization and deserialization of the message:

Write the test class:

package com.leolee.protobuf;

import com.google.protobuf.InvalidProtocolBufferException;

/**
 * @ClassName DataInfoTest
 * @Description: TODO
 * @Author LeoLee
 * @Date 2020/9/2
 * @Version V1.0
 **/
public class DataInfoTest {

    public static void main(String[] args) throws InvalidProtocolBufferException {

        //构造对象
        DataInfo.Student student = DataInfo.Student.newBuilder()
                .setName("LeoLee")
                .setAge(25)
                .setAddress("上海")
                .build();

        byte[] student2ByteArray = student.toByteArray();
        DataInfo.Student student2 = DataInfo.Student.parseFrom(student2ByteArray);

        System.out.println(student2);
        System.out.println(student2.getName());
        System.out.println(student2.getAge());
        System.out.println(student2.getAddress());
    }
}

The results are as follows:

name: "LeoLee"
age: 25
address: "\344\270\212\346\265\267"

LeoLee
25
上海

analysis

Standard message method

So far, protoc’s generation of Java code through the .proto file has been completed. It is noted that the test class uses Java’s construction mode for the construction of the transmission object. Each builder returns a builder, and finally is built by the flow set method. () The construction is complete .

Each message and builder class also contains many other methods that allow you to inspect or manipulate the entire message, including:

  • isInitialized() : Check whether all required fields are set.
  • toString() : Returns a human-readable representation of the message, which is especially useful for debugging.
  • merge gefrom (Message other) : (builder only) merge the content of other into this message, overwrite a single scalar field, merge compound fields, and concatenate repeated fields.
  • clear() : (Only for builder) Clear all fields back to empty state.

These methods implement the interface of message and message.builder, shared by all Java messages and builders. For more information, please refer to the complete Message API DOC .

Parse and serialize

demo, we pass student.toByteArray () to serialize the student message, by DataInfo.Student.parseFrom (student2ByteArray) parse the serialized data (deserialization).

The official website explains as follows:

Each protobuf class contains the use of protobuf binary formatting to read/write the message type you defined

  • byte[] toByteArray(): serialize the message and return a byte array containing the original bytes
  • static Student parseFrom(byte[] data): parse (deserialize) the specified byte array
  • void writeTo(OutputStream output): Serialize the message and write it to an OutputStream
  • static Person parseFrom(InputStream input): read and parse messages from InputStream

These are just a few options for parsing and serialization. Again, please refer to the message API documentation for a complete list

Official warning

I won't translate

Protocol Buffers and O-O Design Protocol buffer classes are basically dumb data holders (like structs in C); they don't make good first class citizens in an object model. If you want to add richer behaviour to a generated class, the best way to do this is to wrap the generated protocol buffer class in an application-specific class. Wrapping protocol buffers is also a good idea if you don't have control over the design of the .proto file (if, say, you're reusing one from another project). In that case, you can use the wrapper class to craft an interface better suited to the unique environment of your application: hiding some data and methods, exposing convenience functions, etc. You should never add behaviour to the generated classes by inheriting from them. This will break internal mechanisms and is not good object-oriented practice anyway.

to sum up

This demo does not seem to be directly related to Netty. You must know that the serialization and parsing process in the demo is equivalent to the process of passing between the client and the server in Netty. After the structured data is serialized, it passes through the socket. Pass it to the receiver, and the receiver deserializes the binary data into readable data . Netty has very good support for protobuf, come on and learn!

Those who need code come here to get it: demo project address

Guess you like

Origin blog.csdn.net/qq_25805331/article/details/108359861