protobuf入门之三种序列化方式比较
前言
学习protobuf需要先知道为什么会有它的存在。前后端之间的协议传输从而产生了流量,在当下力图节省流量成为了趋势。如何使得协议体减小便成为了研发过程中应该去考虑的一个问题。想到以前学习时常说的一句话就是"万物皆对象",在协议这里也可以得到验证。协议的封装其实可以看做是一个对象,前端负责将传递的消息封装在对象中,后端接收后再按照对象的格式去解析。那么,这种“封装为对象并再解析为消息的过程”就被成为序列化与反序列化。
在之前java学习过程中学习过几种序列化方式,比如说:ObjectOutputStream的常规序列化、jackson的ObjectMapper序列化、以及今天要讲解的protobuf序列化方式。在这么多的序列化方式中选择一种合适的方式就成为了研究的目标。下面我们一起探究下如何进行选择。
测试环境
- 测试三种序列化方式的代码将会构造在maven工程下
- 工程如下:
- 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; } }
常规序列化
- 创建TestOfNomral.java,工程如下:
- 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); } }
- 执行结果:
字节数组:[-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序列化
- 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>
- 创建TestOfOM.java,工程如下:
- 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); } }
- 执行结果:
字节数组:[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序列化
-
pom.xml中加入protobuf依赖
<dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.9.0</version> </dependency>
-
protobuf的编译器的环境搭建
①下载protobuf的编译器(这里以MacOS为例)
下载地址
②Mac上配置protoc的环境变量:
③protobuf各语言中的数据类型
详情见地址
④protobuf在java中的案例
详情见地址
⑤协议编译的命令伪代码protoc --proto_path=src --java_out=build/gen src/foo.proto
-
编译器目录结构
-
协议编译.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
-
执行脚本后生成java的协议类
-
将StudentProto3.java拷贝至Idea工程下:
-
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) }
-
创建TestOfPB.java,工程如下:
-
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, 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协议传输协议所占流量少