Java中使用PB教程

前言

之前在写Netty的时候,说过要写一篇关于PB的应用,所以现在兑现承诺。在应用的过程中,发现了很多问题,本文主要介绍两个最关键的问题。

  • PB如何与java项目融合,自动刷新编译,以及pb文件如何与其他项目共用,互不影响。
  • java中如何实现pb的Extension

概述

ProtocolBuff 是 google 提出的的一种数据交换格式,跨语言,跨平台,可扩展。基于这种特性广泛的用于网络数据通信。目前支持的语言有很多,如下:

maven项目集成Java

这里我们主要介绍在一个工程化的项目中如何集成PB,实现PB自动化刷新编译(使用mvn package指令编译),这里我们将引入一个插件protoc-jar-maven-plugin

  • 在pom.xml中加入插件
<plugin>
    <groupId>com.github.os72</groupId>
    <artifactId>protoc-jar-maven-plugin</artifactId>
    <version>3.4.0</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <protocVersion>2.6.1</protocVersion> <!-- 2.4.1, 2.5.0, 2.6.1, 3.4.0 -->
                <includeStdTypes>true</includeStdTypes>
                <inputDirectories>
                    <include>../proto</include>
                </inputDirectories>
                <outputTargets>
                    <outputTarget>
                        <outputDirectory>src/main/java</outputDirectory>
                    </outputTarget>
                </outputTargets>
            </configuration>
        </execution>
    </executions>
</plugin>

重点说明一下配置 configuration

protocVersion:protoc支持的版本,这个需要各端统一。

inputDirectories:pb文件所在的目录,我这里设置成项目工程外的一个目录,目的是为了和其他工程公用一套pb文件

outputTargets:pb文件编译后生产的java文件放置的位置,这里我是放置 src/main/java下,之后你就可以在项目中自由引用。

这样就ok了,在编译maven项目时,你的所有pb文件会跟着自动编译,而且还能和好的与其他工程无缝衔接,免去手动各种烦恼。

PB在java项目中的实战

这里主要说明Extension的问题,对于简单的pb就不做阐述。废话不说直接上代码。

PB文件格式

基础pb文件 Base.proto,所有的extension的pb文件都会import这个文件。

package proto;

// 包格式
message PBDemo
{
    oneof body {
        TestDemoRequest testdemo_req = 1;
        TestDemoResponse testdemo_rsp = 2;
    }
}

message TestDemoRequest
{
    extensions 100   to max;
}

message TestDemoResponse
{
    extensions 100   to max;
}

扩展协议文件 testdemo.proto

package proto.testdemo;

import "base.proto";

extend TestDemoRequest
{
    optional HelloRequest hello_req = 101;
}

extend TestDemoResponse
{
    optional HelloResponse hello_rsp = 101;
}

message HelloRequest
{
    optional string message = 1;
}

message HelloResponse
{
    optional string message = 1;
}

这样的一个pb结构是我们在数据通信中经常使用的,结构,与业务扩展性上都非常好。接下来我们看看,在java中如何对这个解包,和打包。

打包示例

// 打第一个message
Testdemo.HelloRequest.Builder reqBuilder = Testdemo.HelloRequest.newBuilder();
reqBuilder.setMessage(msg);
Testdemo.HelloRequest req = reqBuilder.build();

// 打extension
Base.TestDemoRequest.Builder testBuilder = Base.TestDemoRequest.newBuilder();
testBuilder.setExtension(helloReq, req);

// 打最外层的message
Base.PBDemo.Builder baseBuilder = Base.PBDemo.newBuilder();
Base.PBDemo pbDemo = baseBuilder.setTestdemoReq(testBuilder.build()).build();
byte[] packet = pbDemo.toByteArray();
ByteBuf buf = Unpooled.buffer();
buf.writeBytes(packet);

// 发送数据包
channel.writeAndFlush(buf);

解包示例

ByteBuf buf = (ByteBuf)msg;
byte[] packet = new byte[buf.readableBytes()];
buf.readBytes(packet);

ExtensionRegistry registry = ExtensionRegistry.newInstance();
Testdemo.registerAllExtensions(registry);
Base.PBDemo pbdemo = Base.PBDemo.parseFrom(packet, registry);
Testdemo.HelloResponse rsp = pbdemo.getTestdemoRsp().getExtension(Testdemo.helloRsp);
System.out.println(rsp.getMessage().toString());

代码不做过多解释,可以查看一下两个资料:
ExtensionRegistry
PB Extensions

以上代码demo,都在github上,请大家自行下载, [Git地址](https://github.com/cosysun/NettyDemo.git)

总结

PB的打包解包性能,介于二进制和json之间,同时协议的扩展性,以及数据包压缩功能, 独立于语言和平台特性,都足以让其脱颖而出。

欢迎关注公众号

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值