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之间转换

    面朝大海```春暖花开
  • 相关阅读:
    HDU 3401 Trade
    POJ 1151 Atlantis
    HDU 3415 Max Sum of MaxKsubsequence
    HDU 4234 Moving Points
    HDU 4258 Covered Walkway
    HDU 4391 Paint The Wall
    HDU 1199 Color the Ball
    HDU 4374 One hundred layer
    HDU 3507 Print Article
    GCC特性之__init修饰解析 kasalyn的专栏 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/chywx/p/14525193.html
Copyright © 2011-2022 走看看