protobuf---三种序列化方式比较

本文探讨了三种序列化方式——常规序列化、ObjectMapper序列化和ProtocolBuffer序列化,并通过示例代码展示了它们在Java中的实现。结果显示,protobuf序列化在字节长度上显著减少,流量更节省,适用于高效、流量敏感的协议传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

学习protobuf需要先知道为什么会有它的存在。前后端之间的协议传输从而产生了流量,在当下力图节省流量成为了趋势。如何使得协议体减小便成为了研发过程中应该去考虑的一个问题。想到以前学习时常说的一句话就是"万物皆对象",在协议这里也可以得到验证。协议的封装其实可以看做是一个对象,前端负责将传递的消息封装在对象中,后端接收后再按照对象的格式去解析。那么,这种“封装为对象并再解析为消息的过程”就被成为序列化反序列化
在之前java学习过程中学习过几种序列化方式,比如说:ObjectOutputStream的常规序列化、jackson的ObjectMapper序列化、以及今天要讲解的protobuf序列化方式。在这么多的序列化方式中选择一种合适的方式就成为了研究的目标。下面我们一起探究下如何进行选择。

测试环境

  1. 测试三种序列化方式的代码将会构造在maven工程下
  2. 工程如下:
    在这里插入图片描述
  3. Student.java
    package com.howie;
    
    import java.io.Serializable;
    
    public class Student implements Serializable {
    
        private String username;
        private String password;
        private String email;
        private int age;
        private long timespane;
        private double dValue;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public long getTimespane() {
            return timespane;
        }
    
        public void setTimespane(long timespane) {
            this.timespane = timespane;
        }
    
        public double getdValue() {
            return dValue;
        }
    
        public void setdValue(double dValue) {
            this.dValue = dValue;
        }
    }
    
    

常规序列化

  1. 创建TestOfNomral.java,工程如下:
    在这里插入图片描述
  2. TestOfNomral.java
    package com.howie;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.util.Arrays;
    
    public class TestOfNomral {
    
        public static void normalSerialize(Student student) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = null;
            try {
                oos = new ObjectOutputStream(baos);
                oos.writeObject(student);
                oos.flush();
                byte[] bytes = baos.toByteArray();
                System.out.println("字节数组:" + Arrays.toString(bytes));
                System.out.println("字节数组长度:" + bytes.length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            // 创建student对象并赋值
            Student student = new Student();
    
            student.setUsername("admin");
            student.setPassword("123456");
            student.setEmail("987654321@163.com");
            student.setAge(Integer.MAX_VALUE);
            student.setdValue(Double.MAX_VALUE);
            student.setTimespane(System.currentTimeMillis());
    
            normalSerialize(student);
        }
    }
    
    
  3. 执行结果:
    字节数组:[-84, -19, 0, 5, 115, 114, 0, 17, 99, 111, 109, 46, 104, 111, 119, 105, 101, 46, 83, 116, 117, 100, 101, 110, 116, -105, -32, -118, 3, 35, 32, -70, 68, 2, 0, 6, 73, 0, 3, 97, 103, 101, 68, 0, 6, 100, 86, 97, 108, 117, 101, 74, 0, 9, 116, 105, 109, 101, 115, 112, 97, 110, 101, 76, 0, 5, 101, 109, 97, 105, 108, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 76, 0, 8, 112, 97, 115, 115, 119, 111, 114, 100, 113, 0, 126, 0, 1, 76, 0, 8, 117, 115, 101, 114, 110, 97, 109, 101, 113, 0, 126, 0, 1, 120, 112, 127, -1, -1, -1, 127, -17, -1, -1, -1, -1, -1, -1, 0, 0, 1, 120, -122, -117, -59, -35, 116, 0, 17, 57, 56, 55, 54, 53, 52, 51, 50, 49, 64, 49, 54, 51, 46, 99, 111, 109, 116, 0, 6, 49, 50, 51, 52, 53, 54, 116, 0, 5, 97, 100, 109, 105, 110]
    字节数组长度:183
    
    

ObjectMapper序列化

  1. pom.xml中加入jackson依赖
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.howie</groupId>
        <artifactId>protocol_test</artifactId>
        <version>1.0</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.9.6</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.9.6</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.6</version>
            </dependency>
        </dependencies>
    </project>
    
  2. 创建TestOfOM.java,工程如下:
    在这里插入图片描述
  3. TestOfOM.java
    package com.howie;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import java.util.Arrays;
    
    public class TestOfOM {
    
        public static void jacksonSerialize(Student student) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                String stuStr = mapper.writeValueAsString(student);
                byte[] bytes = stuStr.getBytes("UTF-8");
                System.out.println("字节数组:" + Arrays.toString(bytes));
                System.out.println("字节数组长度:" + bytes.length);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            // 创建student对象并赋值
            Student student = new Student();
    
            student.setUsername("admin");
            student.setPassword("123456");
            student.setEmail("987654321@163.com");
            student.setAge(Integer.MAX_VALUE);
            student.setdValue(Double.MAX_VALUE);
            student.setTimespane(System.currentTimeMillis());
    
            jacksonSerialize(student);
        }
    }
    
    
  4. 执行结果:
    字节数组:[123, 34, 117, 115, 101, 114, 110, 97, 109, 101, 34, 58, 34, 97, 100, 109, 105, 110, 34, 44, 34, 112, 97, 115, 115, 119, 111, 114, 100, 34, 58, 34, 49, 50, 51, 52, 53, 54, 34, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 57, 56, 55, 54, 53, 52, 51, 50, 49, 64, 49, 54, 51, 46, 99, 111, 109, 34, 44, 34, 97, 103, 101, 34, 58, 50, 49, 52, 55, 52, 56, 51, 54, 52, 55, 44, 34, 116, 105, 109, 101, 115, 112, 97, 110, 101, 34, 58, 49, 54, 49, 55, 49, 54, 53, 54, 54, 53, 53, 48, 52, 44, 34, 100, 86, 97, 108, 117, 101, 34, 58, 49, 46, 55, 57, 55, 54, 57, 51, 49, 51, 52, 56, 54, 50, 51, 49, 53, 55, 69, 51, 48, 56, 125]
    字节数组长度:143
    

ProtocolBuffer序列化

  1. pom.xml中加入protobuf依赖

       <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.9.0</version>
       </dependency>
    
  2. protobuf的编译器的环境搭建
    ①下载protobuf的编译器(这里以MacOS为例)
    下载地址
    ②Mac上配置protoc的环境变量:
    在这里插入图片描述
    ③protobuf各语言中的数据类型
    详情见地址
    ④protobuf在java中的案例
    详情见地址
    ⑤协议编译的命令伪代码

    protoc --proto_path=src --java_out=build/gen src/foo.proto
    
  3. 编译器目录结构
    在这里插入图片描述

  4. 协议编译.sh脚本内容:

    #!/bin/bash
    
    proto_path=/Users/weihuanwen/software/JetBrains/protobuf/protoc-3.15.6-osx-x86_64/protomsg
    java_out=$proto_path/javaout
    src=$proto_path/Student.proto3
    
    protoc --proto_path=$proto_path --java_out=$java_out $src
    
  5. 执行脚本后生成java的协议类
    在这里插入图片描述

  6. 将StudentProto3.java拷贝至Idea工程下:
    在这里插入图片描述

  7. StudentProto3.java文件内容:

    // Generated by the protocol buffer compiler.  DO NOT EDIT!
    // source: Student.proto3
    
    package com.howie;
    
    public final class StudentProto3 {
      private StudentProto3() {}
      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 StudentOrBuilder extends
          // @@protoc_insertion_point(interface_extends:Student)
          com.google.protobuf.MessageOrBuilder {
    
        /**
         * <code>string username = 1;</code>
         * @return The username.
         */
        String getUsername();
        /**
         * <code>string username = 1;</code>
         * @return The bytes for username.
         */
        com.google.protobuf.ByteString
            getUsernameBytes();
    
        /**
         * <code>string password = 2;</code>
         * @return The password.
         */
        String getPassword();
        /**
         * <code>string password = 2;</code>
         * @return The bytes for password.
         */
        com.google.protobuf.ByteString
            getPasswordBytes();
    
        /**
         * <code>string email = 3;</code>
         * @return The email.
         */
        String getEmail();
        /**
         * <code>string email = 3;</code>
         * @return The bytes for email.
         */
        com.google.protobuf.ByteString
            getEmailBytes();
    
        /**
         * <code>int32 age = 4;</code>
         * @return The age.
         */
        int getAge();
    
        /**
         * <code>int64 timespane = 5;</code>
         * @return The timespane.
         */
        long getTimespane();
    
        /**
         * <code>double dValue = 6;</code>
         * @return The dValue.
         */
        double getDValue();
      }
      /**
       * Protobuf type {@code Student}
       */
      public static final class Student extends
          com.google.protobuf.GeneratedMessageV3 implements
          // @@protoc_insertion_point(message_implements:Student)
          StudentOrBuilder {
      private static final long serialVersionUID = 0L;
        // Use Student.newBuilder() to construct.
        private Student(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
          super(builder);
        }
        private Student() {
          username_ = "";
          password_ = "";
          email_ = "";
        }
    
        @Override
        @SuppressWarnings({"unused"})
        protected Object newInstance(
            UnusedPrivateParameter unused) {
          return new Student();
        }
    
        @Override
        public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
          return this.unknownFields;
        }
        private Student(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          this();
          if (extensionRegistry == null) {
            throw new NullPointerException();
          }
          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
              com.google.protobuf.UnknownFieldSet.newBuilder();
          try {
            boolean done = false;
            while (!done) {
              int tag = input.readTag();
              switch (tag) {
                case 0:
                  done = true;
                  break;
                case 10: {
                  String s = input.readStringRequireUtf8();
    
                  username_ = s;
                  break;
                }
                case 18: {
                  String s = input.readStringRequireUtf8();
    
                  password_ = s;
                  break;
                }
                case 26: {
                  String s = input.readStringRequireUtf8();
    
                  email_ = s;
                  break;
                }
                case 32: {
    
                  age_ = input.readInt32();
                  break;
                }
                case 40: {
    
                  timespane_ = input.readInt64();
                  break;
                }
                case 49: {
    
                  dValue_ = input.readDouble();
                  break;
                }
                default: {
                  if (!parseUnknownField(
                      input, unknownFields, extensionRegistry, tag)) {
                    done = true;
                  }
                  break;
                }
              }
            }
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw e.setUnfinishedMessage(this);
          } catch (java.io.IOException e) {
            throw new com.google.protobuf.InvalidProtocolBufferException(
                e).setUnfinishedMessage(this);
          } finally {
            this.unknownFields = unknownFields.build();
            makeExtensionsImmutable();
          }
        }
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return StudentProto3.internal_static_Student_descriptor;
        }
    
        @Override
        protected FieldAccessorTable
            internalGetFieldAccessorTable() {
          return StudentProto3.internal_static_Student_fieldAccessorTable
              .ensureFieldAccessorsInitialized(
                  Student.class, Builder.class);
        }
    
        public static final int USERNAME_FIELD_NUMBER = 1;
        private volatile Object username_;
        /**
         * <code>string username = 1;</code>
         * @return The username.
         */
        @Override
        public String getUsername() {
          Object ref = username_;
          if (ref instanceof String) {
            return (String) ref;
          } else {
            com.google.protobuf.ByteString bs = 
                (com.google.protobuf.ByteString) ref;
            String s = bs.toStringUtf8();
            username_ = s;
            return s;
          }
        }
        /**
         * <code>string username = 1;</code>
         * @return The bytes for username.
         */
        @Override
        public com.google.protobuf.ByteString
            getUsernameBytes() {
          Object ref = username_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (String) ref);
            username_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
    
        public static final int PASSWORD_FIELD_NUMBER = 2;
        private volatile Object password_;
        /**
         * <code>string password = 2;</code>
         * @return The password.
         */
        @Override
        public String getPassword() {
          Object ref = password_;
          if (ref instanceof String) {
            return (String) ref;
          } else {
            com.google.protobuf.ByteString bs = 
                (com.google.protobuf.ByteString) ref;
            String s = bs.toStringUtf8();
            password_ = s;
            return s;
          }
        }
        /**
         * <code>string password = 2;</code>
         * @return The bytes for password.
         */
        @Override
        public com.google.protobuf.ByteString
            getPasswordBytes() {
          Object ref = password_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (String) ref);
            password_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
    
        public static final int EMAIL_FIELD_NUMBER = 3;
        private volatile Object email_;
        /**
         * <code>string email = 3;</code>
         * @return The email.
         */
        @Override
        public String getEmail() {
          Object ref = email_;
          if (ref instanceof String) {
            return (String) ref;
          } else {
            com.google.protobuf.ByteString bs = 
                (com.google.protobuf.ByteString) ref;
            String s = bs.toStringUtf8();
            email_ = s;
            return s;
          }
        }
        /**
         * <code>string email = 3;</code>
         * @return The bytes for email.
         */
        @Override
        public com.google.protobuf.ByteString
            getEmailBytes() {
          Object ref = email_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (String) ref);
            email_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
    
        public static final int AGE_FIELD_NUMBER = 4;
        private int age_;
        /**
         * <code>int32 age = 4;</code>
         * @return The age.
         */
        @Override
        public int getAge() {
          return age_;
        }
    
        public static final int TIMESPANE_FIELD_NUMBER = 5;
        private long timespane_;
        /**
         * <code>int64 timespane = 5;</code>
         * @return The timespane.
         */
        @Override
        public long getTimespane() {
          return timespane_;
        }
    
        public static final int DVALUE_FIELD_NUMBER = 6;
        private double dValue_;
        /**
         * <code>double dValue = 6;</code>
         * @return The dValue.
         */
        @Override
        public double getDValue() {
          return dValue_;
        }
    
        private byte memoizedIsInitialized = -1;
        @Override
        public final boolean isInitialized() {
          byte isInitialized = memoizedIsInitialized;
          if (isInitialized == 1) return true;
          if (isInitialized == 0) return false;
    
          memoizedIsInitialized = 1;
          return true;
        }
    
        @Override
        public void writeTo(com.google.protobuf.CodedOutputStream output)
                            throws java.io.IOException {
          if (!getUsernameBytes().isEmpty()) {
            com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_);
          }
          if (!getPasswordBytes().isEmpty()) {
            com.google.protobuf.GeneratedMessageV3.writeString(output, 2, password_);
          }
          if (!getEmailBytes().isEmpty()) {
            com.google.protobuf.GeneratedMessageV3.writeString(output, 3, email_);
          }
          if (age_ != 0) {
            output.writeInt32(4, age_);
          }
          if (timespane_ != 0L) {
            output.writeInt64(5, timespane_);
          }
          if (dValue_ != 0D) {
            output.writeDouble(6, dValue_);
          }
          unknownFields.writeTo(output);
        }
    
        @Override
        public int getSerializedSize() {
          int size = memoizedSize;
          if (size != -1) return size;
    
          size = 0;
          if (!getUsernameBytes().isEmpty()) {
            size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_);
          }
          if (!getPasswordBytes().isEmpty()) {
            size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, password_);
          }
          if (!getEmailBytes().isEmpty()) {
            size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, email_);
          }
          if (age_ != 0) {
            size += com.google.protobuf.CodedOutputStream
              .computeInt32Size(4, age_);
          }
          if (timespane_ != 0L) {
            size += com.google.protobuf.CodedOutputStream
              .computeInt64Size(5, timespane_);
          }
          if (dValue_ != 0D) {
            size += com.google.protobuf.CodedOutputStream
              .computeDoubleSize(6, dValue_);
          }
          size += unknownFields.getSerializedSize();
          memoizedSize = size;
          return size;
        }
    
        @Override
        public boolean equals(final Object obj) {
          if (obj == this) {
           return true;
          }
          if (!(obj instanceof Student)) {
            return super.equals(obj);
          }
          Student other = (Student) obj;
    
          if (!getUsername()
              .equals(other.getUsername())) return false;
          if (!getPassword()
              .equals(other.getPassword())) return false;
          if (!getEmail()
              .equals(other.getEmail())) return false;
          if (getAge()
              != other.getAge()) return false;
          if (getTimespane()
              != other.getTimespane()) return false;
          if (Double.doubleToLongBits(getDValue())
              != Double.doubleToLongBits(
                  other.getDValue())) return false;
          if (!unknownFields.equals(other.unknownFields)) return false;
          return true;
        }
    
        @Override
        public int hashCode() {
          if (memoizedHashCode != 0) {
            return memoizedHashCode;
          }
          int hash = 41;
          hash = (19 * hash) + getDescriptor().hashCode();
          hash = (37 * hash) + USERNAME_FIELD_NUMBER;
          hash = (53 * hash) + getUsername().hashCode();
          hash = (37 * hash) + PASSWORD_FIELD_NUMBER;
          hash = (53 * hash) + getPassword().hashCode();
          hash = (37 * hash) + EMAIL_FIELD_NUMBER;
          hash = (53 * hash) + getEmail().hashCode();
          hash = (37 * hash) + AGE_FIELD_NUMBER;
          hash = (53 * hash) + getAge();
          hash = (37 * hash) + TIMESPANE_FIELD_NUMBER;
          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
              getTimespane());
          hash = (37 * hash) + DVALUE_FIELD_NUMBER;
          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
              Double.doubleToLongBits(getDValue()));
          hash = (29 * hash) + unknownFields.hashCode();
          memoizedHashCode = hash;
          return hash;
        }
    
        public static Student parseFrom(
            java.nio.ByteBuffer data)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data);
        }
        public static Student parseFrom(
            java.nio.ByteBuffer data,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data, extensionRegistry);
        }
        public static Student parseFrom(
            com.google.protobuf.ByteString data)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data);
        }
        public static Student parseFrom(
            com.google.protobuf.ByteString data,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data, extensionRegistry);
        }
        public static Student parseFrom(byte[] data)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data);
        }
        public static Student parseFrom(
            byte[] data,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data, extensionRegistry);
        }
        public static Student parseFrom(java.io.InputStream input)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input);
        }
        public static Student parseFrom(
            java.io.InputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input, extensionRegistry);
        }
        public static Student parseDelimitedFrom(java.io.InputStream input)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseDelimitedWithIOException(PARSER, input);
        }
        public static Student parseDelimitedFrom(
            java.io.InputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
        }
        public static Student parseFrom(
            com.google.protobuf.CodedInputStream input)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input);
        }
        public static Student parseFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input, extensionRegistry);
        }
    
        @Override
        public Builder newBuilderForType() { return newBuilder(); }
        public static Builder newBuilder() {
          return DEFAULT_INSTANCE.toBuilder();
        }
        public static Builder newBuilder(Student prototype) {
          return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
        }
        @Override
        public Builder toBuilder() {
          return this == DEFAULT_INSTANCE
              ? new Builder() : new Builder().mergeFrom(this);
        }
    
        @Override
        protected Builder newBuilderForType(
            BuilderParent parent) {
          Builder builder = new Builder(parent);
          return builder;
        }
        /**
         * Protobuf type {@code Student}
         */
        public static final class Builder extends
            com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
            // @@protoc_insertion_point(builder_implements:Student)
            StudentOrBuilder {
          public static final com.google.protobuf.Descriptors.Descriptor
              getDescriptor() {
            return StudentProto3.internal_static_Student_descriptor;
          }
    
          @Override
          protected FieldAccessorTable
              internalGetFieldAccessorTable() {
            return StudentProto3.internal_static_Student_fieldAccessorTable
                .ensureFieldAccessorsInitialized(
                    Student.class, Builder.class);
          }
    
          // Construct using com.howie.StudentProto3.Student.newBuilder()
          private Builder() {
            maybeForceBuilderInitialization();
          }
    
          private Builder(
              BuilderParent parent) {
            super(parent);
            maybeForceBuilderInitialization();
          }
          private void maybeForceBuilderInitialization() {
            if (com.google.protobuf.GeneratedMessageV3
                    .alwaysUseFieldBuilders) {
            }
          }
          @Override
          public Builder clear() {
            super.clear();
            username_ = "";
    
            password_ = "";
    
            email_ = "";
    
            age_ = 0;
    
            timespane_ = 0L;
    
            dValue_ = 0D;
    
            return this;
          }
    
          @Override
          public com.google.protobuf.Descriptors.Descriptor
              getDescriptorForType() {
            return StudentProto3.internal_static_Student_descriptor;
          }
    
          @Override
          public Student getDefaultInstanceForType() {
            return Student.getDefaultInstance();
          }
    
          @Override
          public Student build() {
            Student result = buildPartial();
            if (!result.isInitialized()) {
              throw newUninitializedMessageException(result);
            }
            return result;
          }
    
          @Override
          public Student buildPartial() {
            Student result = new Student(this);
            result.username_ = username_;
            result.password_ = password_;
            result.email_ = email_;
            result.age_ = age_;
            result.timespane_ = timespane_;
            result.dValue_ = dValue_;
            onBuilt();
            return result;
          }
    
          @Override
          public Builder clone() {
            return super.clone();
          }
          @Override
          public Builder setField(
              com.google.protobuf.Descriptors.FieldDescriptor field,
              Object value) {
            return super.setField(field, value);
          }
          @Override
          public Builder clearField(
              com.google.protobuf.Descriptors.FieldDescriptor field) {
            return super.clearField(field);
          }
          @Override
          public Builder clearOneof(
              com.google.protobuf.Descriptors.OneofDescriptor oneof) {
            return super.clearOneof(oneof);
          }
          @Override
          public Builder setRepeatedField(
              com.google.protobuf.Descriptors.FieldDescriptor field,
              int index, Object value) {
            return super.setRepeatedField(field, index, value);
          }
          @Override
          public Builder addRepeatedField(
              com.google.protobuf.Descriptors.FieldDescriptor field,
              Object value) {
            return super.addRepeatedField(field, value);
          }
          @Override
          public Builder mergeFrom(com.google.protobuf.Message other) {
            if (other instanceof Student) {
              return mergeFrom((Student)other);
            } else {
              super.mergeFrom(other);
              return this;
            }
          }
    
          public Builder mergeFrom(Student other) {
            if (other == Student.getDefaultInstance()) return this;
            if (!other.getUsername().isEmpty()) {
              username_ = other.username_;
              onChanged();
            }
            if (!other.getPassword().isEmpty()) {
              password_ = other.password_;
              onChanged();
            }
            if (!other.getEmail().isEmpty()) {
              email_ = other.email_;
              onChanged();
            }
            if (other.getAge() != 0) {
              setAge(other.getAge());
            }
            if (other.getTimespane() != 0L) {
              setTimespane(other.getTimespane());
            }
            if (other.getDValue() != 0D) {
              setDValue(other.getDValue());
            }
            this.mergeUnknownFields(other.unknownFields);
            onChanged();
            return this;
          }
    
          @Override
          public final boolean isInitialized() {
            return true;
          }
    
          @Override
          public Builder mergeFrom(
              com.google.protobuf.CodedInputStream input,
              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
              throws java.io.IOException {
            Student parsedMessage = null;
            try {
              parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
              parsedMessage = (Student) e.getUnfinishedMessage();
              throw e.unwrapIOException();
            } finally {
              if (parsedMessage != null) {
                mergeFrom(parsedMessage);
              }
            }
            return this;
          }
    
          private Object username_ = "";
          /**
           * <code>string username = 1;</code>
           * @return The username.
           */
          public String getUsername() {
            Object ref = username_;
            if (!(ref instanceof String)) {
              com.google.protobuf.ByteString bs =
                  (com.google.protobuf.ByteString) ref;
              String s = bs.toStringUtf8();
              username_ = s;
              return s;
            } else {
              return (String) ref;
            }
          }
          /**
           * <code>string username = 1;</code>
           * @return The bytes for username.
           */
          public com.google.protobuf.ByteString
              getUsernameBytes() {
            Object ref = username_;
            if (ref instanceof String) {
              com.google.protobuf.ByteString b = 
                  com.google.protobuf.ByteString.copyFromUtf8(
                      (String) ref);
              username_ = b;
              return b;
            } else {
              return (com.google.protobuf.ByteString) ref;
            }
          }
          /**
           * <code>string username = 1;</code>
           * @param value The username to set.
           * @return This builder for chaining.
           */
          public Builder setUsername(
              String value) {
            if (value == null) {
        throw new NullPointerException();
      }
      
            username_ = value;
            onChanged();
            return this;
          }
          /**
           * <code>string username = 1;</code>
           * @return This builder for chaining.
           */
          public Builder clearUsername() {
            
            username_ = getDefaultInstance().getUsername();
            onChanged();
            return this;
          }
          /**
           * <code>string username = 1;</code>
           * @param value The bytes for username to set.
           * @return This builder for chaining.
           */
          public Builder setUsernameBytes(
              com.google.protobuf.ByteString value) {
            if (value == null) {
        throw new NullPointerException();
      }
      checkByteStringIsUtf8(value);
            
            username_ = value;
            onChanged();
            return this;
          }
    
          private Object password_ = "";
          /**
           * <code>string password = 2;</code>
           * @return The password.
           */
          public String getPassword() {
            Object ref = password_;
            if (!(ref instanceof String)) {
              com.google.protobuf.ByteString bs =
                  (com.google.protobuf.ByteString) ref;
              String s = bs.toStringUtf8();
              password_ = s;
              return s;
            } else {
              return (String) ref;
            }
          }
          /**
           * <code>string password = 2;</code>
           * @return The bytes for password.
           */
          public com.google.protobuf.ByteString
              getPasswordBytes() {
            Object ref = password_;
            if (ref instanceof String) {
              com.google.protobuf.ByteString b = 
                  com.google.protobuf.ByteString.copyFromUtf8(
                      (String) ref);
              password_ = b;
              return b;
            } else {
              return (com.google.protobuf.ByteString) ref;
            }
          }
          /**
           * <code>string password = 2;</code>
           * @param value The password to set.
           * @return This builder for chaining.
           */
          public Builder setPassword(
              String value) {
            if (value == null) {
        throw new NullPointerException();
      }
      
            password_ = value;
            onChanged();
            return this;
          }
          /**
           * <code>string password = 2;</code>
           * @return This builder for chaining.
           */
          public Builder clearPassword() {
            
            password_ = getDefaultInstance().getPassword();
            onChanged();
            return this;
          }
          /**
           * <code>string password = 2;</code>
           * @param value The bytes for password to set.
           * @return This builder for chaining.
           */
          public Builder setPasswordBytes(
              com.google.protobuf.ByteString value) {
            if (value == null) {
        throw new NullPointerException();
      }
      checkByteStringIsUtf8(value);
            
            password_ = value;
            onChanged();
            return this;
          }
    
          private Object email_ = "";
          /**
           * <code>string email = 3;</code>
           * @return The email.
           */
          public String getEmail() {
            Object ref = email_;
            if (!(ref instanceof String)) {
              com.google.protobuf.ByteString bs =
                  (com.google.protobuf.ByteString) ref;
              String s = bs.toStringUtf8();
              email_ = s;
              return s;
            } else {
              return (String) ref;
            }
          }
          /**
           * <code>string email = 3;</code>
           * @return The bytes for email.
           */
          public com.google.protobuf.ByteString
              getEmailBytes() {
            Object ref = email_;
            if (ref instanceof String) {
              com.google.protobuf.ByteString b = 
                  com.google.protobuf.ByteString.copyFromUtf8(
                      (String) ref);
              email_ = b;
              return b;
            } else {
              return (com.google.protobuf.ByteString) ref;
            }
          }
          /**
           * <code>string email = 3;</code>
           * @param value The email to set.
           * @return This builder for chaining.
           */
          public Builder setEmail(
              String value) {
            if (value == null) {
        throw new NullPointerException();
      }
      
            email_ = value;
            onChanged();
            return this;
          }
          /**
           * <code>string email = 3;</code>
           * @return This builder for chaining.
           */
          public Builder clearEmail() {
            
            email_ = getDefaultInstance().getEmail();
            onChanged();
            return this;
          }
          /**
           * <code>string email = 3;</code>
           * @param value The bytes for email to set.
           * @return This builder for chaining.
           */
          public Builder setEmailBytes(
              com.google.protobuf.ByteString value) {
            if (value == null) {
        throw new NullPointerException();
      }
      checkByteStringIsUtf8(value);
            
            email_ = value;
            onChanged();
            return this;
          }
    
          private int age_ ;
          /**
           * <code>int32 age = 4;</code>
           * @return The age.
           */
          @Override
          public int getAge() {
            return age_;
          }
          /**
           * <code>int32 age = 4;</code>
           * @param value The age to set.
           * @return This builder for chaining.
           */
          public Builder setAge(int value) {
            
            age_ = value;
            onChanged();
            return this;
          }
          /**
           * <code>int32 age = 4;</code>
           * @return This builder for chaining.
           */
          public Builder clearAge() {
            
            age_ = 0;
            onChanged();
            return this;
          }
    
          private long timespane_ ;
          /**
           * <code>int64 timespane = 5;</code>
           * @return The timespane.
           */
          @Override
          public long getTimespane() {
            return timespane_;
          }
          /**
           * <code>int64 timespane = 5;</code>
           * @param value The timespane to set.
           * @return This builder for chaining.
           */
          public Builder setTimespane(long value) {
            
            timespane_ = value;
            onChanged();
            return this;
          }
          /**
           * <code>int64 timespane = 5;</code>
           * @return This builder for chaining.
           */
          public Builder clearTimespane() {
            
            timespane_ = 0L;
            onChanged();
            return this;
          }
    
          private double dValue_ ;
          /**
           * <code>double dValue = 6;</code>
           * @return The dValue.
           */
          @Override
          public double getDValue() {
            return dValue_;
          }
          /**
           * <code>double dValue = 6;</code>
           * @param value The dValue to set.
           * @return This builder for chaining.
           */
          public Builder setDValue(double value) {
            
            dValue_ = value;
            onChanged();
            return this;
          }
          /**
           * <code>double dValue = 6;</code>
           * @return This builder for chaining.
           */
          public Builder clearDValue() {
            
            dValue_ = 0D;
            onChanged();
            return this;
          }
          @Override
          public final Builder setUnknownFields(
              final com.google.protobuf.UnknownFieldSet unknownFields) {
            return super.setUnknownFields(unknownFields);
          }
    
          @Override
          public final Builder mergeUnknownFields(
              final com.google.protobuf.UnknownFieldSet unknownFields) {
            return super.mergeUnknownFields(unknownFields);
          }
    
    
          // @@protoc_insertion_point(builder_scope:Student)
        }
    
        // @@protoc_insertion_point(class_scope:Student)
        private static final Student DEFAULT_INSTANCE;
        static {
          DEFAULT_INSTANCE = new Student();
        }
    
        public static Student getDefaultInstance() {
          return DEFAULT_INSTANCE;
        }
    
        private static final com.google.protobuf.Parser<Student>
            PARSER = new com.google.protobuf.AbstractParser<Student>() {
          @Override
          public Student parsePartialFrom(
              com.google.protobuf.CodedInputStream input,
              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
              throws com.google.protobuf.InvalidProtocolBufferException {
            return new Student(input, extensionRegistry);
          }
        };
    
        public static com.google.protobuf.Parser<Student> parser() {
          return PARSER;
        }
    
        @Override
        public com.google.protobuf.Parser<Student> getParserForType() {
          return PARSER;
        }
    
        @Override
        public Student getDefaultInstanceForType() {
          return DEFAULT_INSTANCE;
        }
    
      }
    
      private static final com.google.protobuf.Descriptors.Descriptor
        internal_static_Student_descriptor;
      private static final 
        com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internal_static_Student_fieldAccessorTable;
    
      public static com.google.protobuf.Descriptors.FileDescriptor
          getDescriptor() {
        return descriptor;
      }
      private static  com.google.protobuf.Descriptors.FileDescriptor
          descriptor;
      static {
        String[] descriptorData = {
          "\n\016Student.proto3\"l\n\007Student\022\020\n\010username\030" +
          "\001 \001(\t\022\020\n\010password\030\002 \001(\t\022\r\n\005email\030\003 \001(\t\022\013" +
          "\n\003age\030\004 \001(\005\022\021\n\ttimespane\030\005 \001(\003\022\016\n\006dValue" +
          "\030\006 \001(\001B\013\n\tcom.howieb\006proto3"
        };
        descriptor = com.google.protobuf.Descriptors.FileDescriptor
          .internalBuildGeneratedFileFrom(descriptorData,
            new com.google.protobuf.Descriptors.FileDescriptor[] {
            });
        internal_static_Student_descriptor =
          getDescriptor().getMessageTypes().get(0);
        internal_static_Student_fieldAccessorTable = new
          com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
            internal_static_Student_descriptor,
            new String[] { "Username", "Password", "Email", "Age", "Timespane", "DValue", });
      }
    
      // @@protoc_insertion_point(outer_class_scope)
    }
    
    
  8. 创建TestOfPB.java,工程如下:
    在这里插入图片描述

  9. TestOfPB.java:

    package com.howie;
    
    import java.util.Arrays;
    
    import static com.howie.TestOfOM.jacksonSerialize;
    
    public class TestOfPB {
    
        public static void protoSerialize(Student student){
            StudentProto3.Student stu = StudentProto3.Student.newBuilder()
                    .setUsername(student.getUsername())
                    .setPassword(student.getPassword())
                    .setEmail(student.getEmail())
                    .setAge(student.getAge())
                    .setDValue(student.getdValue())
                    .setTimespane(student.getTimespane())
                    .build();
            byte[] bytes = stu.toByteArray();
            System.out.println("字节数组:" + Arrays.toString(bytes));
            System.out.println("字节数组长度:" + bytes.length);
        }
    
        public static void main(String[] args) {
            // 创建student对象并赋值
            Student student = new Student();
    
            student.setUsername("admin");
            student.setPassword("123456");
            student.setEmail("987654321@163.com");
            student.setAge(Integer.MAX_VALUE);
            student.setdValue(Double.MAX_VALUE);
            student.setTimespane(System.currentTimeMillis());
    
            protoSerialize(student);
        }
    }
    
    
  10. 执行结果:

    字节数组:[10, 5, 97, 100, 109, 105, 110, 18, 6, 49, 50, 51, 52, 53, 54, 26, 17, 57, 56, 55, 54, 53, 52, 51, 50, 49, 64, 49, 54, 51, 46, 99, 111, 109, 32, -1, -1, -1, -1, 7, 40, -125, -117, -125, -74, -120, 47, 49, -1, -1, -1, -1, -1, -1, -17, 127]
    字节数组长度:56
    

总结

几种序列化方式比较起来,protobuf协议传输协议所占流量少

附录

参考视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值