ToB企服应用市场:ToB评测及商务社交产业平台
标题:
protobuf对象与JSON相互转换
[打印本页]
作者:
梦见你的名字
时间:
2024-7-18 05:26
标题:
protobuf对象与JSON相互转换
除了之前的 protobuf-java依赖之外,还须要引入 protobuf-java-uti 依赖:
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.19.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.19.1</version>
</dependency>
复制代码
如果不利用protobuf提供的JSON API,而利用fastJson等,直接序列化 com.google.protobuf.Message proto对象,会报错。如果希望利用第三方的JSON API,可以重新界说一个实体类,抽取须要的字段。
一、留意默认值
官网文档:https://protobuf.dev/programming-guides/proto3/#default
官方字段默认值,利用时须要留意:
对于标量消息字段,一旦剖析了消息,就无法判定字段是显式设置为默认值还是根本没有设置(例如布尔值是否设置为false):以是,在界说消息类型时应该记住这一点。例如,如果你不希望某些举动在默认情况下也发生,不要利用布尔值在设置为false时打开某些举动。
如果将标量消息字段设置为其默认值(显式设置),则该值将不会在网络上序列化。
Json 转 proto 对象时,如果Json字符串中的设置为了默认值(显式设置),则该值将不会在网络上序列化。
1、protobuf对象 转 JSON串
// 接收数据反序列化:将字节数据转化为对象数据。
UserProtoBuf.User user = UserProtoBuf.User.parseFrom(byteData);
// 1、proto 对象 转 Json
//获取 Printer对象用于生成JSON字符串
JsonFormat.Printer printer = JsonFormat.printer();
String userJsonStr = printer.print(user);
复制代码
Printer对象天生 JSON字符串时,支持设置一些功能方法。好比:
includingDefaultValueFields():表示 Json输出包含默认值(表现和隐式赋默认值)的字段。
preservingProtoFieldNames():表示利用.proto文件中界说的原始proto字段名而不是将其转换为lowerCamelCase输出。默认 lowerCamelCase的输出。
2、JSON串 转 protobuf对象
// 创建 proto 对象
UserProtoBuf.User.Builder userBuilder = UserProtoBuf.User.newBuilder();
// 2、Json 转 proto 对象
//获取 Parser对象用于解析JSON字符串
JsonFormat.Parser parser = JsonFormat.parser();
parser.merge(userJsonStr2, userBuilder);
复制代码
Parser对象剖析 JSON字符串时,支持设置一些功能方法。好比:
ignoringUnknownFields():表示如果 json 串中存在的属性,proto 对象中不存在,则进行忽略,否则会抛出 InvalidProtocolBufferException异常。
二、示例实战
proto文件内容如下:
syntax = "proto3";
//生成 proto java文件名(一般指定,文件名+自定义。如果不指定,默认时文件名+OuterClass)
option java_outer_classname = "UserProtoBuf";
message User {
int32 age = 1;
int64 timestamp = 2;
bool enabled = 3;
float height = 4;
double weight = 5;
string userName = 6;
string Full_Address = 7;
}
复制代码
1、利用 JsonFormat默认功能
import com.google.protobuf.util.JsonFormat;
public class UserTest {
public static void main(String[] args) throws Exception {
// 将数据序列化
byte[] byteData = getClientPush();
System.out.println("获取到字节数据:byteData长度=" + byteData.length);
System.out.println("===========");
/**
* 接收数据反序列化:将字节数据转化为对象数据。
*/
UserProtoBuf.User user = UserProtoBuf.User.parseFrom(byteData);
System.out.println("==== get获取 user信息:=======");
System.out.println("user信息: \n" + user);
System.out.println("------------------");
System.out.println("getAge= " + user.getAge());
System.out.println("getTimestamp= " + user.getTimestamp());
System.out.println("getEnabled= " + user.getEnabled());
System.out.println("getHeight= " + user.getHeight());
System.out.println("getWeight= " + user.getWeight());
System.out.println("getUserName= " + user.getUserName());
System.out.println("getFullAddress= " + user.getFullAddress());
/**
* proto 对象 转 Json互转
*/
// 1、proto 对象 转 Json
String userJsonStr = JsonFormat.printer()
//.includingDefaultValueFields() // 表示 Json输出包含默认值(显示和隐式赋默认值)的字段。
.print(user);
System.out.println("=====1、proto对象 转 Json字符串:======");
System.out.println("userJsonStr= " + userJsonStr);
// 2、Json 转 proto 对象
String userJsonStr2 = "{\n" +
" "age":18,\n" +
" "timestamp":"1698377283315",\n" +
" "enabled":false,\n" +
" "height":1.8,\n" +
" "weight":66.76,\n" +
" "userName":"赵云"\n" +
"}";
// 创建 proto 对象
UserProtoBuf.User.Builder userBuilder = UserProtoBuf.User.newBuilder();
JsonFormat.parser()
//.ignoringUnknownFields() // 表示如果 json 串中存在的属性,proto 对象中不存在,则进行忽略,否则会抛出 InvalidProtocolBufferException异常
.merge(userJsonStr2, userBuilder);
UserProtoBuf.User user1 = userBuilder.build();
System.out.println("=====2、Json 转 proto 对象:======");
System.out.println("user1信息: \n" + user1);
System.out.println("------------------");
}
/**
* 模拟发送方,将数据序列化后发送
*
* @return
*/
private static byte[] getClientPush() {
// 按照定义的数据结构,创建一个对象。
UserProtoBuf.User.Builder user = UserProtoBuf.User.newBuilder();
user.setAge(18);
user.setTimestamp(System.currentTimeMillis());
user.setEnabled(false);
//user.setEnabled(true);
//user.setHeight(1.88F);
user.setWeight(66.76D);
user.setUserName("赵云");
//user.setFullAddress("王者-打野");
/**
* 发送数据序列化:将对象数据转化为字节数据输出
*/
UserProtoBuf.User userBuild = user.build();
byte[] bytes = userBuild.toByteArray();
return bytes;
}
}
复制代码
2、设置 JsonFormat处理功能
这里利用 JsonFormat的这两个方法。其他方法自行查看。
Printer对象利用 includingDefaultValueFields()方法。
Parser对象利用 ignoringUnknownFields()方法。
将上面这两个方法的解释打开,运行结果如下:
– 求知若饥,虚心若愚。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4