下载protoc编译器

去github下载最新release版:https://github.com/protocolbuffers/protobuf/releases
然后将 bin 目录和 include 目录都放在项目路径下,建议与 src 同级

引入Maven依赖

  1. <dependency>
  2. <groupId>com.google.protobuf</groupId>
  3. <artifactId>protobuf-java</artifactId>
  4. <version>3.11.4</version>
  5. </dependency>

配置Maven插件(本地版)

            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <extensions>true</extensions>
                <configuration>
                    <!-- 配置.proto所在路径 -->
                    <protoSourceRoot>${project.basedir}/proto-src</protoSourceRoot>
                    <!-- 配置代码生成的根目录,如果.proto中设置了package或option java_package,会在根目录下生成层级目录 -->
                    <outputDirectory>${project.build.sourceDirectory}</outputDirectory>
                    <!-- 设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件 -->
          <!-- 最好设置成false,避免.proto文件中忘记写包导致源码目录被清掉 -->
                    <clearOutputDirectory>false</clearOutputDirectory>
                    <!-- 临时文件生成路径 -->
                    <temporaryProtoFileDirectory>${project.build.directory}/protoc-temp</temporaryProtoFileDirectory>
          <!-- protoc执行文件路径 -->
                    <protocExecutable>${project.basedir}/tools/proto/bin/protoc.exe</protocExecutable>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

配置Maven插件(在线版)

配置方法来自grpc的配置向导:https://github.com/grpc/grpc-java#generated-code

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <extensions>true</extensions>
                <configuration>
                    <!-- 基础配置 -->
                    <protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.31.0:exe:${os.detected.classifier}</pluginArtifact>

                    <!-- 配置.proto所在路径 -->
                    <protoSourceRoot>${project.basedir}/proto-src</protoSourceRoot>
                    <!-- 配置代码生成的根目录,如果.proto中设置了package或option java_package,会在根目录下生成层级目录 -->
                    <outputDirectory>${project.build.sourceDirectory}</outputDirectory>
                    <!-- 设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件 -->
                    <!-- 最好设置成false,避免.proto文件中忘记写包导致源码目录被清掉 -->
                    <clearOutputDirectory>false</clearOutputDirectory>
                    <!-- 临时文件生成路径 -->
                    <temporaryProtoFileDirectory>${project.build.directory}/protoc-temp</temporaryProtoFileDirectory>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

编写proto文件

这里目前先只提供一个简单示例:

syntax = "proto3";

// protobuf命名空间
package tutorial;

// 设置java包名,这个包名会覆盖package
option java_package = "com.semonx.protobuf.proto";
// 生成多个类文件。默认是false,只会生成一个.java文件,其他类都以内部静态类的方式存在
option java_multiple_files = true;
// outer_class的名字,注意不要和内部类的名字重了
// option java_outer_classname = "SearchRequest";


message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

生成代码

运行 mvn compile 就可以生成proto class,并编译源码

简单使用

    @Test
    void testProtobuf() throws InvalidProtocolBufferException {
        SearchRequest searchRequest = SearchRequest.newBuilder()
                .setQuery("World")
                .setPageNumber(10)
                .setResultPerPage(2)
                .build();

        byte[] bs = searchRequest.toByteArray();

        SearchRequest request2 = SearchRequest.parseFrom(bs);
        System.out.println(request2.getQuery() + " | " + request2.getPageNumber() + " | " + request2.getResultPerPage());
    }