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
- 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>
- protobuf-maven-plugin</artifactId>
- <version>0.6.1</version>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
-
- <protocExecutable>protoc</protocExecutable>
-
-
- </configuration>
- </plugin>
- </plugins>
- </build>
复制代码
- 插件默认读取文件夹/src/main/proto下的proto文件去编译
- 在文件夹target/generated-sources/protobuf/java下会生成对应pojo的protobuf操作类
注意:
- 若执行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
- 若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 {
- /**
- * string name = 1;
- * @return The name.
- */
- java.lang.String getName();
- /**
- * string name = 1;
- * @return The bytes for name.
- */
- com.google.protobuf.ByteString
- getNameBytes();
- /**
- * int32 id = 2;
- * @return The id.
- */
- int getId();
- /**
- * repeated string emails = 3;
- * @return A list containing the emails.
- */
- java.util.List<java.lang.String>
- getEmailsList();
- /**
- * repeated string emails = 3;
- * @return The count of emails.
- */
- int getEmailsCount();
- /**
- * repeated string emails = 3;
- * @param index The index of the element to return.
- * @return The emails at the given index.
- */
- java.lang.String getEmails(int index);
- /**
- * repeated string emails = 3;
- * @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_ = "";
- /**
- * string name = 1;
- * @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;
- }
- }
- /**
- * string name = 1;
- * @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;
- /**
- * int32 id = 2;
- * @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();
- /**
- * repeated string emails = 3;
- * @return A list containing the emails.
- */
- public com.google.protobuf.ProtocolStringList
- getEmailsList() {
- return emails_;
- }
- /**
- * repeated string emails = 3;
- * @return The count of emails.
- */
- public int getEmailsCount() {
- return emails_.size();
- }
- /**
- * repeated string emails = 3;
- * @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);
- }
- /**
- * repeated string emails = 3;
- * @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_ = "";
- /**
- * string name = 1;
- * @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;
- }
- }
- /**
- * string name = 1;
- * @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;
- }
- }
- /**
- * string name = 1;
- * @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;
- }
- /**
- * string name = 1;
- * @return This builder for chaining.
- */
- public Builder clearName() {
- name_ = getDefaultInstance().getName();
- bitField0_ = (bitField0_ & ~0x00000001);
- onChanged();
- return this;
- }
- /**
- * string name = 1;
- * @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_ ;
- /**
- * int32 id = 2;
- * @return The id.
- */
- @java.lang.Override
- public int getId() {
- return id_;
- }
- /**
- * int32 id = 2;
- * @param value The id to set.
- * @return This builder for chaining.
- */
- public Builder setId(int value) {
- id_ = value;
- bitField0_ |= 0x00000002;
- onChanged();
- return this;
- }
- /**
- * int32 id = 2;
- * @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;
- }
- /**
- * repeated string emails = 3;
- * @return A list containing the emails.
- */
- public com.google.protobuf.ProtocolStringList
- getEmailsList() {
- emails_.makeImmutable();
- return emails_;
- }
- /**
- * repeated string emails = 3;
- * @return The count of emails.
- */
- public int getEmailsCount() {
- return emails_.size();
- }
- /**
- * repeated string emails = 3;
- * @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);
- }
- /**
- * repeated string emails = 3;
- * @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);
- }
- /**
- * repeated string emails = 3;
- * @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;
- }
- /**
- * repeated string emails = 3;
- * @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;
- }
- /**
- * repeated string emails = 3;
- * @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;
- }
- /**
- * repeated string emails = 3;
- * @return This builder for chaining.
- */
- public Builder clearEmails() {
- emails_ =
- com.google.protobuf.LazyStringArrayList.emptyList();
- bitField0_ = (bitField0_ & ~0x00000004);;
- onChanged();
- return this;
- }
- /**
- * repeated string emails = 3;
- * @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依赖的版本。
- <dependency>
- <groupId>com.google.protobuf</groupId>
- protobuf-java</artifactId>
- <version>4.31.1</version>
- </dependency>
复制代码- 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的性能
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- junit-jupiter-api</artifactId>
- <version>5.8.2</version>
- </dependency>
- <dependency>
- <groupId>org.openjdk.jmh</groupId>
- jmh-core</artifactId>
- <version>1.37</version>
- </dependency>
- <dependency>
- <groupId>org.openjdk.jmh</groupId>
- jmh-generator-annprocess</artifactId>
- <version>1.37</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- jackson-databind</artifactId>
- <version>2.15.2</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- jackson-core</artifactId>
- <version>2.15.2</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- jackson-annotations</artifactId>
- <version>2.15.2</version>
- </dependency>
- <dependency>
- <groupId>cn.hutool</groupId>
- hutool-all</artifactId>
- <version>5.8.27</version>
- </dependency>
复制代码- 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;
- }
- }
复制代码 运行结果
- 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序列化和反序列化的性能。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |