zoukankan      html  css  js  c++  java
  • protobuf基于java和javascript的使用

    ProtoBuf介绍

    ProtoBuf 是google团队开发的用于高效存储和读取结构化数据的工具,google出品,必属精品。
    目前最新版本为3。文档地址:https://developers.google.com/protocol-buffers/docs/proto3
    相比于xmljsonprotobuf压缩率更高,传输高效,自然很节省流量。
    protobuf支持跨语言,貌似前后端使用javaJavaScript的众多吧。

    整理下java和JavaScript的例子

    需要下载protoc可执行文件。通过编写.proto,命令生成相应的文件,比如java,js等。

    编写Person.proto。
    具体语法可以查看官网,这是最基础的一个对象。

    syntax = "proto3";
    option java_package = "com.dahai.protobuf";
    option java_outer_classname = "PersonModel";
    
    message Person {
      int32 id = 1;
      string name = 2;
      int32 age = 3;
      string email = 4;
    }
    

    可以通过protoc命令生成,此处为了方便起见,使用maven plugin来生成(原理一直,会下载相应的protoc可执行文件)

    创建maven工程,在resources目录创建proto文件夹,将示例文件Person.proto放入改文件夹下。

    pom.xml引入相应依赖

        <dependency>
          <groupId>com.google.protobuf</groupId>
          <artifactId>protobuf-java</artifactId>
          <version>3.11.1</version>
        </dependency>
    

    pom.xml引入相应的插件

    
      <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>
            <!--指定项目的proto文件目录-->
              <protoSourceRoot>src/main/resources/proto</protoSourceRoot>
              <clearOutputDirectory>false</clearOutputDirectory>
              <!--不存在会自动下载-->
              <protocArtifact>
                com.google.protobuf:protoc:3.11.1:exe:${os.detected.classifier}
              </protocArtifact>
              <pluginId>grpc-java</pluginId>
            </configuration>
            <executions>
              <execution>
                <goals>
                  <goal>compile</goal>
                  <goal>compile-custom</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    

    执行标红箭头的命令即可生成。

    将生成的文件放入相应的包下面即可

    demo测试

        @Test
        public void test3() throws InvalidProtocolBufferException {
            // 创建person对象
            Person person = Person.newBuilder()
                .setId(1)
                .setName("陈海洋")
                .setAge(18)
                .setEmail("1559843332@qq.com")
                .build();
    
            System.out.println(person);
    
            // 反序列化获取person
            byte[] bytes = person.toByteArray();
            Person newPerson = Person.parseFrom(bytes);
            System.out.println(newPerson);
        }
    

    使用protobuf是为了节省用户流量,来实战下。

    java作为服务端+客户端测试

    // 暴露接口,返回二进制数据
    @GetMapping("/person/{id}")
    public byte[] person(@PathVariable("id") Integer id) {
    
        Person person = Person.newBuilder()
            .setId(id)
            .setName("陈海洋")
            .setAge(18)
            .setEmail("1559843332@qq.com")
            .build();
    
        return person.toByteArray();
    }
        
    // RestTemplate客户端测试
    @Test
    public void test1() throws IOException {
    
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://localhost:8881/demo/person/2";
        ResponseEntity<Resource> forEntity = restTemplate.getForEntity(url, Resource.class);
        Person person = Person.parseFrom(forEntity.getBody().getInputStream());
        System.out.println(person);
        
    }
    

    客户端前端调用示例

    既然是跨平台,js肯定也是可以解析二进制流的。
    前端也可以通过proto文件生成相应的js。如下是js反序列化示例
    为了写前端demo,也是爬了好多坑,都是泪啊!(本想基于原生的)

    import messages from '../../utils/proto/person.js'
    
    axios({
      method: 'get',
      url: 'http://localhost:8881/demo/person/10',
      responseType: 'arraybuffer'
    }).then((res) => {
        console.log('res.data', res.data)
        var person = messages.Person.decode(new Uint8Array(res.data))
        console.log('java', person)
        console.log('java id', person.id)
      }
    )
    

    这只是demo,实际项目一般不会反悔bety[]数据。在我们的业务中是通过websocket来传输的。

    项目地址

    https://github.com/chywx/spring-boot-chy/tree/master/chy-protobuf

    参考

    用Maven实现一个protobuf的Java例子

    protobufjs语法

    axios 基本用法

    JS中ArrayBuffer和Uint8Array区别

    HTML5 Blob与ArrayBuffer、TypeArray和字符串String之间转换

    面朝大海```春暖花开
  • 相关阅读:
    android窗口管理剖析
    android Activity管理简析
    LeetCode第三十四题-寻找数组中对应目标值的首尾索引
    LeetCode第三十三题-判断字符串中最长的有效括号数
    LeetCode第三十二题-判断字符串中最长的有效括号数
    LeetCode第三十一题-下一个排列
    LeetCode第三十题-字符串中具有所有单词串联的子串
    LeetCode第二十九题-整数除法
    LeetCode第二十八题-判断字符串是否包含子字符串
    LeetCode第二十七题-删除数组指定元素
  • 原文地址:https://www.cnblogs.com/chywx/p/14525193.html
Copyright © 2011-2022 走看看