物联网 Protobuf文本协议入门
Protobuf(Protocol Buffers)是Google开发的高效、跨语言的序列化框架,相比JSON/XML等文本协议,Protobuf在性能、空间占用和跨语言支持方面具有显著优势
源码
源码[https://gitee.com/kcnf-webrtc/iot-sample/tree/master/protobuf/protobuf-api-01]
proto文件定义与语法规范
基础语法
定义用户数据结构的示例文件(src/main/proto/user.proto):
syntax = "proto3";
package com.jysemel.iot.protobuf;
option java_package = "com.jysemel.protobuf.model";
option java_outer_classname = "UserProto";
message User {
int32 id = 1;
string name = 2;
string email = 3;
int32 age = 4;
}
针对上面关键语法说明
| 语法项 | 说明 |
|---|---|
| syntax = "proto3" | 指定使用Protocol Buffers v3版本 |
| option java_package | 定义生成的Java类包路径 |
| option java_outer_classname | 定义生成的外层类名(用于嵌套消息) |
| repeated | 定义列表类型字段,对应Java中的List或数组 |
注意事项
- 其中User和java_outer_classname 名称不要冲突,否则编译出现下面错误
protoc did not exit cleanly. Review output for more information.

添加依赖
<?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>
<parent>
<groupId>com.jysemel.iot</groupId>
<artifactId>iot-sample</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>protobuf</artifactId>
<packaging>pom</packaging>
<modules>
<module>protobuf-api-01</module>
<module>protobuf-api-02</module>
<module>protobuf-sample01</module>
<module>protobuf-sample</module>
</modules>
<properties>
<protobuf.version>3.21.12</protobuf.version>
</properties>
<dependencies>
<!-- Protobuf Java 支持 -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
<!-- 可选:支持更便捷的 Protobuf 消息转换 -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<!-- OS 检测插件,用于 protobuf 插件 -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.0</version>
</extension>
</extensions>
<plugins>
<!-- Spring Boot Maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Protobuf 编译插件 -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.21.12:exe:${os.detected.classifier}</protocArtifact>
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
执行编译后面代码

序列化与反序列化示例
package com.jysemel.iot;
import com.google.protobuf.InvalidProtocolBufferException;
import com.jysemel.protobuf.model.UserProto;
public class ProtoBufDemo {
public static void main(String[] args) {
// 1. 构建User对象
UserProto.User user = UserProto.User.newBuilder()
.setId(123)
.setName("Alice")
.setEmail("alice@example.com")
.setAge(25)
.build();
// 2. 序列化为字节数组
byte[] data = user.toByteArray();
System.out.println("Serialized data length: " + data.length);
// 3. 反序列化
try {
UserProto.User parsedUser = UserProto.User.parseFrom(data);
System.out.println("Parsed User: " + parsedUser);
System.out.println("Name: " + parsedUser.getName());
System.out.println("Email: " + parsedUser.getEmail());
System.out.println("Age: " + parsedUser.getAge());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
}
关键方法说明
| 方法 | 说明 |
|---|---|
| toByteArray() | 将消息序列化为字节数组 |
| writeTo(OutputStream) | 将消息写入输出流(适用于网络传输) |
| parseFrom(byte[]) | 从字节数组反序列化消息 |
| parseDelimitedFrom(InputStream) | 从带长度前缀的输入流反序列化消息(适用于流式传输) |
Protobuf与JSON互转
package com.jysemel.iot;
import com.google.protobuf.util.JsonFormat;
import com.jysemel.protobuf.model.UserProto;
public class JsonConversionDemo {
public static void main(String[] args) throws Exception {
// 1. 构建User对象
UserProto.User user = UserProto.User.newBuilder()
.setId(123)
.setName("Alice")
.setEmail("alice@example.com")
.setAge(25)
.build();
// Protobuf转JSON
String json = JsonFormat.printer().print(user);
System.out.println("JSON: " + json);
// JSON转Protobuf
UserProto.User.Builder builder = UserProto.User.newBuilder();
JsonFormat.parser().merge(json, builder);
UserProto.User parsedUser = builder.build();
System.out.println("Parsed from JSON: " + parsedUser);
}
}
