1. 程式人生 > >Protocol Buffer 之 Java 使用(基於Spring Boot 2.x)

Protocol Buffer 之 Java 使用(基於Spring Boot 2.x)

開發環境:使用Intellij IDEA + Maven + Spring Boot 2.x + JDK 8

1.在專案的pom.xml檔案下,引入protobuf的Jar開發包依賴;並且可以配置protobuf 的Maven外掛,對編寫的proto檔案編譯成Java檔案。

    <properties>
        <protobuf.version>3.6.1</protobuf.version>
        <grpc.version>1.16.1</grpc.version>
    </properties>

    <dependencies>
    	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>${protobuf.version}</version>
        </dependency>
    </dependencies>

    <build>
        <extensions>
            <extension>
                <!-- provides os.detected.classifier (i.e. linux-x86_64, osx-x86_64) property -->
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.1</version>
            </extension>
        </extensions>

        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
  
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                    <!-- proto檔案目錄 -->
                    <protoSourceRoot>${project.basedir}/src/main/proto/protobuf</protoSourceRoot>
                    <!-- 生成的Java檔案目錄 -->
                    <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
                    <!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

新增完protobuf的編譯外掛之後,可以在編輯器的右邊看到外掛操作,如下圖:
在這裡插入圖片描述
通過點選protobuf:compile,就可以將編寫的proto檔案生成到對應的資料夾。這裡上面配置的proto檔案目錄是 p r o j e c

t . b a s e d i r /
s r c / m a i n / p r o t o / p r o t o b u f {project.basedir}/src/main/proto/protobuf(不配置的話預設是 {project.basedir}/src/main/proto),配置的生成的Java檔案目錄是 p r o j e c t . b u i l d . d i r e c t o r y / g e n e r a t e d s o u r c e s / p r o t o b u f / j a v a {project.build.directory}/generated-sources/protobuf/java(不配置的話預設是 {project.build.directory}/generated-sources/protobuf/java)。這個可以根據自己的需要進行指定。

2.為了支援網路協議的接收和傳送以protobuf格式進行,我們需要為Spring Boot 配置protobuf的序列化和反序列化。

protobuf序列化的作用是將協議體以protobuf的格式response回去,反序列化是在構造發生協議請求時,用protobuf的格式。
具體的Java配置程式碼示例如下:

package com.dbfor.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;

@Configuration
public class ProtobufConfig {

    /**
     * protobuf 序列化
     * @return
     */
    @Bean
    ProtobufHttpMessageConverter protobufHttpMessageConverter() {
        return new ProtobufHttpMessageConverter();
    }

    /**
     * protobuf 反序列化
     * @param converter
     * @return
     */
    @Bean
    RestTemplate restTemplate(ProtobufHttpMessageConverter converter) {
        return new RestTemplate(Collections.singletonList(converter));
    }
}

3.接下來,在處理請求回覆時,可以直接返回protobuf的物件型別MessageLite。程式示例如下:

@GetMapping(path = "/info/{id}")
    public MessageLite taskInfoRequest(@PathVariable("id") long id) {
    	// ...
        // return 對應的protobuf的物件型別MessageLite
    }