ProtoBuf及整合到SpringBoot

mitesi 2020-04-07

Protobuf(Google Protocol Buffer)是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议

protobuf是跨语言的,并且自带一个编译器(protoc),只需要用protoc进行编译,就可以编译成Java、Python、C++、C#、Go等多种语言代码,然后可以直接使用,不需要再写其它代码,自带有解析的代码。

对于结构中的每个成员会提供set系列函数和get系列函数。

protobuf的优点:

性能好/效率高,序列化和反序列化的时间开销都很小

与XML和JSON格式相比,protobuf更小、更快、更便捷

扩展性好,兼容性好

支持多种语言

protobuf的不足:

采用二进制编码,可读性差

缺乏自描述,二进制的协议内容必须配合.proto文件的定义才有含义

protoc.exe 下载 https://github.com/protocolbuffers/protobuf/releases

添加protobuf文件user.proto

syntax = "proto3";

option java_package = "com.example.demo.protobuf";
option java_outer_classname = "MessageUser";

message MessageUserLogin {
    string access_token = 1;
    string username = 2;
}

使用protoc.exe生成java文件

protoc.exe --java_out=./ user.proto

将生成的MessageUser.java放到对应的位置,如

com\example\demo\protobuf

添加依赖

<dependency>
       <groupId>com.google.protobuf</groupId>
       <artifactId>protobuf-java</artifactId>
       <version>3.11.4</version>
</dependency>
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
        <artifactId>protobuf-java-format</artifactId>
        <version>1.4</version>
</dependency>

添加protobuf序列化支持

package com.example.demo;

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 CommonConfig {
    /**
     * protobuf 序列化
     */
    @Bean
    ProtobufHttpMessageConverter protobufHttpMessageConverter() {
        return new ProtobufHttpMessageConverter();
    }

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

控制器

package com.example.demo.controller;

import com.example.demo.protobuf.MessageUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@Slf4j
@RestController
public class DemoController {

    @RequestMapping(value = "/test", produces = "application/x-protobuf")
    @ResponseBody
    public MessageUser.MessageUserLogin getProto() {
        MessageUser.MessageUserLogin.Builder builder =  MessageUser.MessageUserLogin.newBuilder();
        builder.setAccessToken(UUID.randomUUID().toString()+"_res");
        builder.setUsername("abc");
        return builder.build();
    }

}

启动项目

GET  http://127.0.0.1:8080/test

结果为

(2fa3543c-4155-45be-bfd9-19e0ebdb98bb_resabc

可以看出这种结果适合给机器看

添加测试

package com.example.demo;

import com.example.demo.protobuf.MessageUser;
import org.junit.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.net.URI;

public class DemoApplicationTests {
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://127.0.0.1:8080")
            .defaultHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)")
            .defaultCookie("ACCESS_TOKEN", "test_token").build();

    @Test
    public void test() {
        try {
            URI uri = new URI("http", null, "127.0.0.1", 8080, "/demo/test", "", null);
            try {
                Mono<MessageUser.MessageUserLogin> resp = webClient.method(HttpMethod.GET).uri("test")
                        .retrieve()
                        .bodyToMono(MessageUser.MessageUserLogin.class);
                MessageUser.MessageUserLogin data = resp.block();
                System.out.println("token----- " + data.getAccessToken());
                System.out.println("username----- " + data.getUsername());
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {

        }
    }
}

token----- ba2c8328-ea33-48ab-ad07-beb3a10eacfc_res
username----- abc

相关推荐