辟谷期间可以吃什么| 干咳吃什么药止咳效果好| 关节错缝术是什么意思| 两面性是什么意思| 幽门螺杆菌感染吃什么药| 嘴唇发红是什么原因| 什么有什么造句| 端午节应该吃什么| 右后背疼什么原因| 十万个为什么作者是谁| 危日是什么意思| 人为什么会得阑尾炎| 2017 年是什么年| 企业bg是什么意思| 身上肉疼是什么原因| 康熙雍正乾隆是什么关系| 蜜蜂糖冲开水有什么好处| 冠状动脉ct检查什么| plcc是什么意思| 四川人为什么喜欢吃辣| 什么字五行属水| 为什么外阴老是长疖子| 做梦数钱是什么意思啊| 什么是灰指甲| 女性失眠吃什么药最好| notebook什么意思| 7月5号是什么星座| 胎位rsa是什么意思| 竖心旁的字和什么有关| 深千尺是什么意思| 吉士粉是什么粉| 牛后腿肉适合做什么| 脸上长肉疙瘩是什么原因| cmyk代表什么颜色| 阴道炎用什么药好| 一个点是什么意思| 为什么会流口水| 上环什么时候去最合适| 人走茶凉下一句是什么| 湿气重吃什么中药好| 冉字五行属什么| 喝酒睡不着是什么原因| 股骨头在什么位置| 唐伯虎属什么生肖| 梦见自己生男孩是什么意思| 蛇酒不是三十九开什么| 忧愁是什么意思| 难以启齿什么意思| 特警力量第二部叫什么| 为什么生日不能提前过| 尿检白细胞弱阳性是什么意思| 又双叒叕念什么啥意思| 大脚趾头麻木是什么原因| 为什么总是放屁很频繁| 肾结石是什么原因造成的| 颈椎不好挂什么科| 膀胱炎挂什么科| 为什么不建议年轻人做肠镜| 甘草有什么功效| 子宫瘢痕是什么意思| 乳腺钙化是什么意思| 制作人是干什么的| 左下腹疼痛挂什么科| 郑板桥爱画什么| 71是什么意思| 农历10月24日是什么星座| 腐竹和什么一起炒好吃| 多囊是什么病| cla是什么| 头昏和头晕有什么区别| 玫瑰金是什么颜色| 扁平足是什么| 没吃多少东西但肚子很胀是什么| 军绿色是什么颜色| 做b超能查出什么| 孕囊是什么样的图片| 十一月九号是什么星座| 尿路感染吃什么药比较好的快| 中国在什么半球| 为什么太阳会发光| 什么是黄褐斑| 什么叫末法时代| 暗语是什么意思| 女人吃芡实有什么好处| 抗甲状腺球蛋白抗体高是什么原因| 韬的意思是什么| 中医学专业学什么| 什么是红斑狼疮病| 冬枣什么时候成熟| 什么叫阴吹| 什么季节最短| 天津是什么省| 布谷鸟叫有什么征兆| 润滑油是干什么用的| 宽粉是什么做的| 破瓦法是什么| skap是什么牌子| 崩大碗配什么煲汤最好| 稷是什么作物| 雨霖铃是什么意思| 官运是什么意思| 低血压吃什么药| 怀孕做梦梦到蛇是什么意思| 胸闷气短什么原因| chest是什么意思| 出家人不打诳语是什么意思| 里急后重吃什么药最好| 大姨妈推迟是什么原因| 前列腺炎是什么原因引起| 北方的木瓜叫什么| 什么是肠息肉| 红黑相间的蛇是什么蛇| 白羊座是什么象星座| 腮腺炎吃什么药最管用| 大汗淋漓是什么意思| 为什么会无缘无故长痣| 腰间盘突出有什么好的治疗方法| 胶原蛋白的成分是什么| 丹青指什么| 吃东西没有味道是什么原因| lining是什么意思| 羊水指数和羊水深度有什么区别| 体外射精什么意思| 尿道口红肿是什么原因| hpv是什么原因引起的| 什么泡水喝对肝脏好| 冬菜是什么菜| 福五行属什么| 提拔是什么意思| 艾滋病的症状是什么样| slogan是什么意思啊| 心脏扩大吃什么药好| 月经提前是什么原因引起的| 什么的原野| 睾丸炎用什么药| 嗜碱性粒细胞偏高是什么原因| 探花是什么意思| 腹胀便溏是什么意思| 鉴黄师是什么职业| 11是什么意思| 老是肚子疼是什么原因| 魏大勋什么星座| 准生证需要什么材料| idh是什么意思| 不自主的摇头是什么病| 举案齐眉是什么意思| 流涎是什么意思| 尿酸高是什么| 什么大专好就业| 白斑是什么病| 油条吃多了有什么危害| 前列腺炎吃什么中药| 静待花开的前一句是什么| 低钾血症吃什么药| 没事找事是什么意思| 片仔癀为什么这么贵| 尿等待吃什么药最好| 水灵灵是什么意思| 嘴无味是什么病的征兆| 黄金芽是什么茶| 苔菜是什么菜图片| 烤麸是什么| 身先士卒是什么意思| 孕酮低吃什么可以提高孕酮| 什么叫溶血| hpvhr阳性什么意思| 营养不良会导致身体出现什么症状| 本卦和变卦是什么关系| 朋友圈为什么发不出去| 羊肉馅饺子配什么菜好| 云是由什么组成的| 五蕴指什么| 怀孕是什么症状| 什么水果养胃又治胃病| 什么叫轻断食| 为什么血液是红色的| 干什么呢| 胎发什么时候剃最合适| 熬夜伤什么器官| 什么花园| 纯磨玻璃结节是什么意思| 姓蓝的是什么民族| 拘禁是什么意思| 总ige高是什么意思| 核磁共振挂什么科| 肚子容易饿是什么原因| b型血为什么叫贵族血| 水清则无鱼什么意思| 正方形的纸能折什么| 属兔与什么属相相克| 头发爱出油是什么原因| 罗姓男孩取什么名字好| 冠状ct能查什么| spoRT是什么| 亥五行属什么| 甲沟炎是什么症状| mrd是什么| gas是什么意思| 为什么会得卵巢肿瘤| 停诊是什么意思| 维u是什么药| 世态炎凉什么意思| 保险凭证号是什么| 霉菌性炎症用什么药效果最好| 艾滋病简称什么| 及笄是什么意思| 孕妇梦见狗是什么意思| 应无所住什么意思| 嘴唇黑是什么原因| 狗狗胰腺炎吃什么药| 怀孕孕酮低吃什么补得快| 破执是什么意思| 爱情是什么颜色的| 冬虫夏草长什么样| 女人上嘴唇有痣代表什么| 泉中水是什么生肖| 什么是援交| 草字头加全念什么| 梦见好多西瓜是什么意思| 凉粉果什么时候成熟| 漂流穿什么衣服| 扁桃体为什么会发炎| 循序渐进什么意思| 终其一生下一句是什么| 除湿气吃什么好| 充电宝充电慢是什么原因| 茯苓不能和什么一起吃| 6月有什么水果| 献殷勤是什么意思| 萎缩性胃炎可以吃什么水果| 百分比是什么意思| 吃什么对眼睛好| 男人嘴唇薄代表什么| 什么津津| 为什么一生气就胃疼| 来月经同房会有什么后果| 贵子是什么意思| 五戒十善是什么| 老年人补什么钙效果最好| 牛仔裙配什么上衣好看| 嫩牛五方什么意思| 小产可以吃什么水果| 菊苣别名叫什么| 国保大队是干什么的| 橘子什么季节成熟| 嘴唇紫红色是什么原因| 什么什么之年| 白色配什么颜色好看| t1w1高信号代表什么| 知了吃了有什么好处| 打完升白针有什么反应| 最好的减肥方法是什么| 容易受惊吓是什么原因| 维生素c阴性什么意思| 痘痘肌肤适合用什么牌子的护肤品| 胆囊切除后对身体有什么影响| 持续高烧不退是什么原因| 二级b超是检查什么| 看血脂高挂什么科| 夏天防中暑备什么药| 吃海带有什么好处| 甲肝戊肝是什么病| 筋是什么| 术后吃什么刀口恢复得快| 百度

高效编解码协议之protobuf协议详解

百度 ”这时他一回头,才发现自己爱人带着儿子站在了背后。

Protocol Buffers(简称 protobuf)是 Google 开发的 高效二进制序列化工具,用于结构化数据的存储和传输。

核心特性

特性 说明
跨语言支持 支持 Java、C++、Python、Go 等主流语言。
高效编解码 二进制格式,比 JSON/XML 更小、更快。
强类型约束 通过 .proto 文件定义数据结构,避免运行时错误。
向后兼容 支持字段扩展(新增字段不影响旧代码)。

使用指南

开发环境

  • windows
  • jetbrains idea
  • maven_3.9.7
  • jdk_8
  • protobuf_31.1

安装编译器(protoc)

配置

  • 将下载的压缩包解压出来,新增环境变量protobuf=文件夹路径
  • 编辑环境变量Path,新增%protobuf%\bin

验证

# 打开cmd命令行,执行以下命令
protoc --version

# 输出结果如下,表示安装成功
libprotoc 31.1

定义数据结构

  • 新建person.proto文件
// person.proto
syntax = "proto3";

message Person {
  string name = 1;
  int32 id = 2;
  repeated string emails = 3;
}

编译

手动执行命令

# 打开cmd命令行,切换到person.proto文件目录下,执行以下命令
protoc --java_out=./ ./person.proto

# 当前目录下会生成PersonOuterClass.java文件
# 将PersonOuterClass.java复制到对应项目目录就可以使用了
# PersonOuterClass.java默认没有package路径,需要手动加一下

maven插件编译

  • 在pom.xml中加入以下代码,执行maven的clean compile
<build>
  <plugins>
    <plugin>
      <groupId>org.xolstice.maven.plugins</groupId>
      <artifactId>protobuf-maven-plugin</artifactId>
      <version>0.6.1</version>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <!-- 从 Path 中查找 -->
        <protocExecutable>protoc</protocExecutable>
        <!-- 或直接指定路径 -->
        <!--<protocExecutable>xxx\bin\protoc.exe</protocExecutable>-->
      </configuration>
    </plugin>
  </plugins>
</build>
  • 插件默认读取文件夹/src/main/proto下的proto文件去编译
  • 在文件夹target/generated-sources/protobuf/java下会生成对应pojo的protobuf操作类

注意:

  1. 若执行protoc命令之后idea报如下错误:Module 'my-test' production: java.lang.ClassCastException: class org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType cannot be cast to class org.jetbrains.jps.builders.java.dependencyView.TypeRepr$ClassType (org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType and org.jetbrains.jps.builders.java.dependencyView.TypeRepr$ClassType are in unnamed module of loader java.net.URLClassLoader @2f2c9b19)。则清除一下idea的缓存,然后执行rebuild
  2. 若idea的terminal或者maven执行compile的时候报错未找到protoc命令,则可以在terminal中执行以下命令排查idea是否读取到最新的Path。若打印的Path值没有protoc的路径,则重启一下电脑。
# terminal中使用的是powershell的话执行
echo $env:path

# terminal中使用的是cmd的话执行
echo %path%

编译结果示例

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: person.proto
// Protobuf Java Version: 4.31.1

@com.google.protobuf.Generated
public final class PersonOuterClass {
  private PersonOuterClass() {}
  static {
    com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      /* major= */ 4,
      /* minor= */ 31,
      /* patch= */ 1,
      /* suffix= */ "",
      PersonOuterClass.class.getName());
  }
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  public interface PersonOrBuilder extends
      // @@protoc_insertion_point(interface_extends:Person)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>string name = 1;</code>
     * @return The name.
     */
    java.lang.String getName();
    /**
     * <code>string name = 1;</code>
     * @return The bytes for name.
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>int32 id = 2;</code>
     * @return The id.
     */
    int getId();

    /**
     * <code>repeated string emails = 3;</code>
     * @return A list containing the emails.
     */
    java.util.List<java.lang.String>
        getEmailsList();
    /**
     * <code>repeated string emails = 3;</code>
     * @return The count of emails.
     */
    int getEmailsCount();
    /**
     * <code>repeated string emails = 3;</code>
     * @param index The index of the element to return.
     * @return The emails at the given index.
     */
    java.lang.String getEmails(int index);
    /**
     * <code>repeated string emails = 3;</code>
     * @param index The index of the value to return.
     * @return The bytes of the emails at the given index.
     */
    com.google.protobuf.ByteString
        getEmailsBytes(int index);
  }
  /**
   * Protobuf type {@code Person}
   */
  public static final class Person extends
      com.google.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:Person)
      PersonOrBuilder {
  private static final long serialVersionUID = 0L;
    static {
      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
        /* major= */ 4,
        /* minor= */ 31,
        /* patch= */ 1,
        /* suffix= */ "",
        Person.class.getName());
    }
    // Use Person.newBuilder() to construct.
    private Person(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
    }
    private Person() {
      name_ = "";
      emails_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return PersonOuterClass.internal_static_Person_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return PersonOuterClass.internal_static_Person_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              PersonOuterClass.Person.class, PersonOuterClass.Person.Builder.class);
    }

    public static final int NAME_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private volatile java.lang.Object name_ = "";
    /**
     * <code>string name = 1;</code>
     * @return The name.
     */
    @java.lang.Override
    public java.lang.String getName() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        name_ = s;
        return s;
      }
    }
    /**
     * <code>string name = 1;</code>
     * @return The bytes for name.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ID_FIELD_NUMBER = 2;
    private int id_ = 0;
    /**
     * <code>int32 id = 2;</code>
     * @return The id.
     */
    @java.lang.Override
    public int getId() {
      return id_;
    }

    public static final int EMAILS_FIELD_NUMBER = 3;
    @SuppressWarnings("serial")
    private com.google.protobuf.LazyStringArrayList emails_ =
        com.google.protobuf.LazyStringArrayList.emptyList();
    /**
     * <code>repeated string emails = 3;</code>
     * @return A list containing the emails.
     */
    public com.google.protobuf.ProtocolStringList
        getEmailsList() {
      return emails_;
    }
    /**
     * <code>repeated string emails = 3;</code>
     * @return The count of emails.
     */
    public int getEmailsCount() {
      return emails_.size();
    }
    /**
     * <code>repeated string emails = 3;</code>
     * @param index The index of the element to return.
     * @return The emails at the given index.
     */
    public java.lang.String getEmails(int index) {
      return emails_.get(index);
    }
    /**
     * <code>repeated string emails = 3;</code>
     * @param index The index of the value to return.
     * @return The bytes of the emails at the given index.
     */
    public com.google.protobuf.ByteString
        getEmailsBytes(int index) {
      return emails_.getByteString(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!com.google.protobuf.GeneratedMessage.isStringEmpty(name_)) {
        com.google.protobuf.GeneratedMessage.writeString(output, 1, name_);
      }
      if (id_ != 0) {
        output.writeInt32(2, id_);
      }
      for (int i = 0; i < emails_.size(); i++) {
        com.google.protobuf.GeneratedMessage.writeString(output, 3, emails_.getRaw(i));
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (!com.google.protobuf.GeneratedMessage.isStringEmpty(name_)) {
        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, name_);
      }
      if (id_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, id_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < emails_.size(); i++) {
          dataSize += computeStringSizeNoTag(emails_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getEmailsList().size();
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof PersonOuterClass.Person)) {
        return super.equals(obj);
      }
      PersonOuterClass.Person other = (PersonOuterClass.Person) obj;

      if (!getName()
          .equals(other.getName())) return false;
      if (getId()
          != other.getId()) return false;
      if (!getEmailsList()
          .equals(other.getEmailsList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + NAME_FIELD_NUMBER;
      hash = (53 * hash) + getName().hashCode();
      hash = (37 * hash) + ID_FIELD_NUMBER;
      hash = (53 * hash) + getId();
      if (getEmailsCount() > 0) {
        hash = (37 * hash) + EMAILS_FIELD_NUMBER;
        hash = (53 * hash) + getEmailsList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static PersonOuterClass.Person parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static PersonOuterClass.Person parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static PersonOuterClass.Person parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static PersonOuterClass.Person parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static PersonOuterClass.Person parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static PersonOuterClass.Person parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static PersonOuterClass.Person parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessage
          .parseWithIOException(PARSER, input);
    }
    public static PersonOuterClass.Person parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessage
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    public static PersonOuterClass.Person parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessage
          .parseDelimitedWithIOException(PARSER, input);
    }

    public static PersonOuterClass.Person parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessage
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static PersonOuterClass.Person parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessage
          .parseWithIOException(PARSER, input);
    }
    public static PersonOuterClass.Person parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessage
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(PersonOuterClass.Person prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code Person}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:Person)
        PersonOuterClass.PersonOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return PersonOuterClass.internal_static_Person_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return PersonOuterClass.internal_static_Person_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                PersonOuterClass.Person.class, PersonOuterClass.Person.Builder.class);
      }

      // Construct using PersonOuterClass.Person.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        name_ = "";
        id_ = 0;
        emails_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return PersonOuterClass.internal_static_Person_descriptor;
      }

      @java.lang.Override
      public PersonOuterClass.Person getDefaultInstanceForType() {
        return PersonOuterClass.Person.getDefaultInstance();
      }

      @java.lang.Override
      public PersonOuterClass.Person build() {
        PersonOuterClass.Person result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public PersonOuterClass.Person buildPartial() {
        PersonOuterClass.Person result = new PersonOuterClass.Person(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(PersonOuterClass.Person result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.name_ = name_;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.id_ = id_;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          emails_.makeImmutable();
          result.emails_ = emails_;
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof PersonOuterClass.Person) {
          return mergeFrom((PersonOuterClass.Person)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(PersonOuterClass.Person other) {
        if (other == PersonOuterClass.Person.getDefaultInstance()) return this;
        if (!other.getName().isEmpty()) {
          name_ = other.name_;
          bitField0_ |= 0x00000001;
          onChanged();
        }
        if (other.getId() != 0) {
          setId(other.getId());
        }
        if (!other.emails_.isEmpty()) {
          if (emails_.isEmpty()) {
            emails_ = other.emails_;
            bitField0_ |= 0x00000004;
          } else {
            ensureEmailsIsMutable();
            emails_.addAll(other.emails_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                name_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                id_ = input.readInt32();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 26: {
                java.lang.String s = input.readStringRequireUtf8();
                ensureEmailsIsMutable();
                emails_.add(s);
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object name_ = "";
      /**
       * <code>string name = 1;</code>
       * @return The name.
       */
      public java.lang.String getName() {
        java.lang.Object ref = name_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          name_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>string name = 1;</code>
       * @return The bytes for name.
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        java.lang.Object ref = name_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          name_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string name = 1;</code>
       * @param value The name to set.
       * @return This builder for chaining.
       */
      public Builder setName(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        name_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <code>string name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearName() {
        name_ = getDefaultInstance().getName();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }
      /**
       * <code>string name = 1;</code>
       * @param value The bytes for name to set.
       * @return This builder for chaining.
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        name_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }

      private int id_ ;
      /**
       * <code>int32 id = 2;</code>
       * @return The id.
       */
      @java.lang.Override
      public int getId() {
        return id_;
      }
      /**
       * <code>int32 id = 2;</code>
       * @param value The id to set.
       * @return This builder for chaining.
       */
      public Builder setId(int value) {

        id_ = value;
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <code>int32 id = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        id_ = 0;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringArrayList emails_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      private void ensureEmailsIsMutable() {
        if (!emails_.isModifiable()) {
          emails_ = new com.google.protobuf.LazyStringArrayList(emails_);
        }
        bitField0_ |= 0x00000004;
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @return A list containing the emails.
       */
      public com.google.protobuf.ProtocolStringList
          getEmailsList() {
        emails_.makeImmutable();
        return emails_;
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @return The count of emails.
       */
      public int getEmailsCount() {
        return emails_.size();
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @param index The index of the element to return.
       * @return The emails at the given index.
       */
      public java.lang.String getEmails(int index) {
        return emails_.get(index);
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @param index The index of the value to return.
       * @return The bytes of the emails at the given index.
       */
      public com.google.protobuf.ByteString
          getEmailsBytes(int index) {
        return emails_.getByteString(index);
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @param index The index to set the value at.
       * @param value The emails to set.
       * @return This builder for chaining.
       */
      public Builder setEmails(
          int index, java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureEmailsIsMutable();
        emails_.set(index, value);
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @param value The emails to add.
       * @return This builder for chaining.
       */
      public Builder addEmails(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureEmailsIsMutable();
        emails_.add(value);
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @param values The emails to add.
       * @return This builder for chaining.
       */
      public Builder addAllEmails(
          java.lang.Iterable<java.lang.String> values) {
        ensureEmailsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, emails_);
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearEmails() {
        emails_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
        bitField0_ = (bitField0_ & ~0x00000004);;
        onChanged();
        return this;
      }
      /**
       * <code>repeated string emails = 3;</code>
       * @param value The bytes of the emails to add.
       * @return This builder for chaining.
       */
      public Builder addEmailsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        ensureEmailsIsMutable();
        emails_.add(value);
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:Person)
    }

    // @@protoc_insertion_point(class_scope:Person)
    private static final PersonOuterClass.Person DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new PersonOuterClass.Person();
    }

    public static PersonOuterClass.Person getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<Person>
        PARSER = new com.google.protobuf.AbstractParser<Person>() {
      @java.lang.Override
      public Person parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Person> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Person> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public PersonOuterClass.Person getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_Person_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_Person_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static  com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\014person.proto\"2\n\006Person\022\014\n\004name\030\001 \001(\t\022\n" +
      "\n\002id\030\002 \001(\005\022\016\n\006emails\030\003 \003(\tb\006proto3"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        });
    internal_static_Person_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_Person_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_Person_descriptor,
        new java.lang.String[] { "Name", "Id", "Emails", });
    descriptor.resolveAllFeaturesImmutable();
  }

  // @@protoc_insertion_point(outer_class_scope)
}

执行

从上面编译出来的文件中可以找到这行注释// Protobuf Java Version: 4.31.1,表示protobuf对应java依赖的版本。

  • 在pom.xml中引入依赖
<!-- Protobuf Java -->
<dependency>
  <groupId>com.google.protobuf</groupId>
  <artifactId>protobuf-java</artifactId>
  <version>4.31.1</version>
</dependency>
  • java测试代码
public static void main(String[] args) throws InvalidProtocolBufferException {
    // 构造对象
    PersonOuterClass.Person person = PersonOuterClass.Person.newBuilder()
    .setName("Alice")
    .setId(123)
    .addEmails("alice@example.com")
    .build();

    // 序列化为字节数组
    byte[] bytes = person.toByteArray();

    // 反序列化
    PersonOuterClass.Person parsedPerson = PersonOuterClass.Person.parseFrom(bytes);
    System.out.println(parsedPerson.getName());
    System.out.println(parsedPerson.getId());
    System.out.println(parsedPerson.getEmails(0));

}
  • 执行结果
Alice
123
alice@example.com

性能测试

protobuf和json的性能对比

此处对比protobuf、hutool的json工具类、jackson的性能

  • 引入依赖
<!-- JUnit 5 -->
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
  <version>5.8.2</version>
</dependency>
<!-- jmh性能测试 -->
<dependency>
  <groupId>org.openjdk.jmh</groupId>
  <artifactId>jmh-core</artifactId>
  <version>1.37</version>
</dependency>
<!-- 编译时处理JMH的注解,若不加,编译出来的benchmark注解未被解析,运行时会报错 -->
<dependency>
  <groupId>org.openjdk.jmh</groupId>
  <artifactId>jmh-generator-annprocess</artifactId>
  <version>1.37</version>
  <scope>provided</scope>
</dependency>

<!-- jackson 依赖 -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.15.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.15.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.15.2</version>
</dependency>

<!-- hutool 依赖 -->
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.8.27</version>
</dependency>
  • 测试的pojo类
public class PersonJson {

    private String name;
    private int id;
    private String[] emails;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String[] getEmails() {
        return emails;
    }

    public void setEmails(String[] emails) {
        this.emails = emails;
    }
}

  • 测试代码
package protobuf;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.openjdk.jmh.annotations.*;

import java.io.IOException;

@Warmup(iterations = 2, time = 1)
@Measurement(iterations = 2, time = 1)
@Fork(2)
@State(Scope.Thread)
public class ProtobufBenchmark {
    private PersonOuterClass.Person person;
    private byte[] serializedData;
    private String jsonStr;

    private PersonJson personJson;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Setup
    public void setup() {
        person = PersonOuterClass.Person.newBuilder()
                .setName("Charlie")
                .setId(789)
                .addEmails("charlie@example.com")
                .build();
        serializedData = person.toByteArray();

        personJson = new PersonJson();
        personJson.setName("Charlie");
        personJson.setId(789);
        personJson.setEmails(new String[]{"charlie@example.com"});

        jsonStr = JSONUtil.toJsonStr(personJson);
    }

    /**
     * 测试protobuf序列化
     *
     * @return
     */
    @Benchmark
    public byte[] testSerialize() {
        return person.toByteArray();
    }

    /**
     * 测试protobuf反序列化
     *
     * @return
     * @throws Exception
     */
    @Benchmark
    public PersonOuterClass.Person testDeserialize() throws Exception {
        return PersonOuterClass.Person.parseFrom(serializedData);
    }

    /**
     * 测试hutool-json序列化
     *
     * @return
     */
    @Benchmark
    public String testJsonSerialize() {
        return JSONUtil.toJsonStr(personJson);
    }

    /**
     * 测试hutool-json反序列化
     *
     * @return
     */
    @Benchmark
    public PersonJson testJsonDeserialize() {
        return JSONUtil.toBean(jsonStr, PersonJson.class);
    }

    /**
     * 测试Jackson序列化
     *
     * @return
     * @throws JsonProcessingException
     */
    @Benchmark
    public String testJacksonSerialize() throws JsonProcessingException {
        return objectMapper.writeValueAsString(personJson);
    }

    /**
     * 测试Jackson反序列化
     *
     * @return
     * @throws Exception
     */
    @Benchmark
    public PersonJson testJacksonDeserialize() throws Exception {
        return objectMapper.readValue(jsonStr, PersonJson.class);
    }

}

运行结果

Benchmark                                  Mode  Cnt         Score         Error  Units
ProtobufBenchmark.testSerialize           thrpt    4  23652174.844 ± 1801935.493  ops/s
ProtobufBenchmark.testDeserialize         thrpt    4   7830878.513 ± 2204277.060  ops/s
ProtobufBenchmark.testJacksonSerialize    thrpt    4   5737731.097 ±  975288.754  ops/s
ProtobufBenchmark.testJacksonDeserialize  thrpt    4   2806124.511 ±  396224.766  ops/s
ProtobufBenchmark.testJsonSerialize       thrpt    4    256885.571 ±   42109.112  ops/s
ProtobufBenchmark.testJsonDeserialize     thrpt    4    289602.156 ±   78181.194  ops/s
  • protobuf序列化性能是jackson的4倍,反序列化性能也将近3倍
  • hutool的json性能就比较差了,所以实际项目中若要使用json,推荐使用jackson

小结

本文介绍了protobuf从安装到使用的全过程,并提供了相应的代码示例。读者可以通过直接运行代码示例直观的学习到protobuf如何使用。最后测试和对比了protobuf、json序列化和反序列化的性能。

posted @ 2025-08-03 21:49  竹堑  阅读(134)  评论(0)    收藏  举报
女生肾疼是什么原因 为什么一直拉肚子 破伤风针有什么作用 体内火气大吃什么降火 三楼属于五行属什么
孙权和孙策是什么关系 手术后喝什么鱼汤最好 水烧开后有白色沉淀物是什么 肯定是什么意思 含量是什么意思
尿白细胞弱阳性是什么意思 sry什么意思 imao什么意思 b型阳性血是什么意思 豆加支念什么
左进右出有什么讲究 什么叫偏光眼镜 pears是什么意思 物以类聚形容什么动物 鸭子什么意思
清关是什么意思hcv8jop1ns3r.cn 梦见茄子是什么意思1949doufunao.com 什么驴技穷成语hcv8jop3ns8r.cn 汲汲营营是什么意思hcv8jop5ns8r.cn 才高八斗代表什么生肖hcv8jop4ns7r.cn
钴对人体有什么伤害hcv7jop6ns4r.cn 杀破狼是什么意思hcv8jop1ns1r.cn 佛陀是什么意思wuhaiwuya.com 小孩坐火车需要什么证件hcv8jop3ns2r.cn strange是什么意思hcv8jop4ns1r.cn
八面玲珑指什么生肖hcv8jop4ns1r.cn 什么的白云hcv8jop7ns0r.cn polo衫是什么hcv9jop6ns5r.cn 姓名字号是什么意思hcv8jop4ns4r.cn 观音得道日是什么时候hcv7jop6ns4r.cn
天兵神将是什么动物hcv8jop5ns4r.cn 什么网名好听hcv9jop4ns0r.cn 鸡全蛋粉是什么东西hcv9jop8ns0r.cn 社会是什么hcv8jop5ns3r.cn 引火归元是什么意思hcv8jop7ns8r.cn
百度