Protobuf 实例(java)

Posted 地表最强菜鸡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Protobuf 实例(java)相关的知识,希望对你有一定的参考价值。

最近项目中需要使用Protobuf作为设备端到云端通信的数据压缩协议,特此记录便于日后查阅。

maven依赖如下:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.15.8</version>
</dependency>

protobuf文件名为 d_cook_records.proto,内容如下:

syntax = "proto3";
import "google/protobuf/any.proto";
// option java_package="com.galanz.iot.content.restapi.model.proto";
option java_outer_classname="DCookRecordsProto";

// DCookRecords
message DCookRecords {
    repeated DCookRecord records = 1;
}
// DCookRecord
message DCookRecord {
	int32 record_type = 1;
	string record_producer = 2;
    int64 record_start_time = 3;
    int64 record_end_time = 4;
    google.protobuf.Any record_value = 5;
}
// ProgramRecordValue record_type = 1 or 2
message ProgramRecordValue {
    string content_code = 1;
    int32 content_version = 2;
    string dimension = 3;
    repeated TempRecord oven_temp_list = 4;
    repeated TempRecord probe_temp_list = 5;
}
// RecipeRecordValue record_type = 3
message RecipeRecordValue {
	int64 recipe_id = 1;
    string recipe_code = 2;
    string dimension = 3;
    repeated TempRecord oven_temp_list = 4;
    repeated TempRecord probe_temp_list = 5;
}
message TempRecord {
	int32 temp = 1;
	int64 timestamp = 2;
}

注:protobuf属性解释可以参照另一篇文章,传送门:Protobuf 属性解释

在Java中的写法,代码如下:

@Override
public Boolean insertRecord(String record) throws InvalidProtocolBufferException {
    //ProtoBuf组装
    DCookRecordsProto.ProgramRecordValue.Builder value1 = DCookRecordsProto.ProgramRecordValue.newBuilder();
    value1.setContentCode("xxx")
            .setContentVersion(1)
            .setDimension("xx#xx");
    for (int i = 0; i < 2; i++) {
        DCookRecordsProto.TempRecord.Builder tempRecord = DCookRecordsProto.TempRecord.newBuilder();
        tempRecord.setTemp(100 + i + 1).setTimestamp(System.currentTimeMillis());
        value1.addOvenTempList(tempRecord);
        value1.addProbeTempList(tempRecord);
    }
    DCookRecordsProto.DCookRecord.Builder cookRecord = DCookRecordsProto.DCookRecord.newBuilder();
    cookRecord.setRecordType(1)
            .setRecordProducer("d")
            .setRecordStartTime(System.currentTimeMillis())
            .setRecordEndTime(System.currentTimeMillis())
            .setRecordValue(Any.pack(value1.build()));
    DCookRecordsProto.DCookRecords.Builder cookRecords = DCookRecordsProto.DCookRecords.newBuilder();
    cookRecords.addRecords(cookRecord);
    byte[] bytes = cookRecords.build().toByteArray();
    //Base64 Encoded
    String encoded = Base64.getEncoder().encodeToString(bytes);
    System.out.println("---------encoded----------");
    System.out.println(encoded);
    //ProtoBuf反解析
    final String did = LoginUtils.getDid();
    List<RmCookRecordPo> recordPoList = Lists.newArrayList();
    byte[] decoded = Base64.getDecoder().decode(record);
    DCookRecordsProto.DCookRecords records = DCookRecordsProto.DCookRecords.parseFrom(decoded);
    if (!(ObjectUtils.isEmpty(records) || CollectionUtils.isEmpty(records.getRecordsList()))) {
        for (DCookRecordsProto.DCookRecord record1 : records.getRecordsList()) {
            RmCookRecordPo recordPo = new RmCookRecordPo();
            recordPo.setDid(did);
            if (record1.getRecordStartTime() > 0) {
                Instant instant = Instant.ofEpochMilli(record1.getRecordStartTime());
                recordPo.setRecordStartTime(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
            }
            if (record1.getRecordEndTime() > 0) {
                Instant instant = Instant.ofEpochMilli(record1.getRecordEndTime());
                recordPo.setRecordEndTime(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
            }
            recordPo.setRecordProducer(record1.getRecordProducer());
            recordPo.setRecordType(record1.getRecordType());
            if (record1.getRecordType() == 1 || record1.getRecordType() == 2) {
                DCookRecordsProto.ProgramRecordValue recordValue = record1.getRecordValue()
                        .unpack(DCookRecordsProto.ProgramRecordValue.class);
                ProgramRecordValue programRecordValue = new ProgramRecordValue();
                programRecordValue.setContentCode(recordValue.getContentCode());
                programRecordValue.setContentVersion(recordValue.getContentVersion());
                programRecordValue.setDimension(recordValue.getDimension());
                if (!CollectionUtils.isEmpty(recordValue.getOvenTempListList())) {
                    List<TempRecord> tempRecordList = Lists.newArrayList();
                    for (DCookRecordsProto.TempRecord ovenTemp : recordValue.getOvenTempListList()) {
                        TempRecord tempRecord = new TempRecord();
                        tempRecord.setTemp(ovenTemp.getTemp());
                        tempRecord.setTimestamp(ovenTemp.getTimestamp());
                        tempRecordList.add(tempRecord);
                    }
                    programRecordValue.setOvenTempListList(tempRecordList);
                }
                if (!CollectionUtils.isEmpty(recordValue.getProbeTempListList())) {
                    List<TempRecord> tempRecordList = Lists.newArrayList();
                    for (DCookRecordsProto.TempRecord protoTemp : recordValue.getProbeTempListList()) {
                        TempRecord tempRecord = new TempRecord();
                        tempRecord.setTemp(protoTemp.getTemp());
                        tempRecord.setTimestamp(protoTemp.getTimestamp());
                        tempRecordList.add(tempRecord);
                    }
                    programRecordValue.setProbeTempListList(tempRecordList);
                }
                recordPo.setRecordValue(JSONObject.toJSONString(programRecordValue));
            } else if (record1.getRecordType() == 2) {
                DCookRecordsProto.RecipeRecordValue recordValue = record1.getRecordValue()
                        .unpack(DCookRecordsProto.RecipeRecordValue.class);
                RecipeRecordValue recipeRecordValue = new RecipeRecordValue();
                recipeRecordValue.setRecipeId(recordValue.getRecipeId());
                recipeRecordValue.setRecipeCode(recordValue.getRecipeCode());
                recipeRecordValue.setDimension(recordValue.getDimension());
                if (!CollectionUtils.isEmpty(recordValue.getOvenTempListList())) {
                    List<TempRecord> tempRecordList = Lists.newArrayList();
                    for (DCookRecordsProto.TempRecord ovenTemp : recordValue.getOvenTempListList()) {
                        TempRecord tempRecord = new TempRecord();
                        tempRecord.setTemp(ovenTemp.getTemp());
                        tempRecord.setTimestamp(ovenTemp.getTimestamp());
                        tempRecordList.add(tempRecord);
                    }
                    recipeRecordValue.setOvenTempListList(tempRecordList);
                }
                if (!CollectionUtils.isEmpty(recordValue.getProbeTempListList())) {
                    List<TempRecord> tempRecordList = Lists.newArrayList();
                    for (DCookRecordsProto.TempRecord protoTemp : recordValue.getProbeTempListList()) {
                        TempRecord tempRecord = new TempRecord();
                        tempRecord.setTemp(protoTemp.getTemp());
                        tempRecord.setTimestamp(protoTemp.getTimestamp());
                        tempRecordList.add(tempRecord);
                    }
                    recipeRecordValue.setProbeTempListList(tempRecordList);
                }
                recordPo.setRecordValue(JSONObject.toJSONString(recipeRecordValue));
            }
            recordPoList.add(recordPo);
        }
    }
    //入库
    if (!CollectionUtils.isEmpty(recordPoList)) {
        baseMapper.batchInsertCookRecordList(recordPoList);
    }
    return true;
}

到此 Protobuf 使用实例(java)介绍完成。

以上是关于Protobuf 实例(java)的主要内容,如果未能解决你的问题,请参考以下文章

solr分布式索引实战分片配置读取:工具类configUtil.java,读取配置代码片段,配置实例

Protostuff一键序列化工具Protobuf JAVA实现

java 代码片段

Protobuf协议的Java应用例子

protobuf 库在消息实例化时抛出 FatalException

ProtoBuf WCF“未分配模型实例”