java中使用protobuf的详细说明

protobuf在idea中的配置

首先需要下载protoc.exe文件,随后打开idea,点击setting找到Plugins,下载如下两个插件
在这里插入图片描述
下载安装完成后重启idea,点击Tools->Configure Genprotobuf
在这里插入图片描述
protoc path定位到下载的protoc.exe解析器的位置,将Quick Gen选中java并勾选下面的java

编写代码并测试

定义demo.proto文件

syntax = "proto3";
package MONITOR;

import "google/protobuf/any.proto";

enum ESensorType
{
	E_VRTRIX = 0;

	E_MYO = 1;

	E_VHAND = 2;

	E_MOCAP = 3;

	E_POSITION = 4;
}


enum ECmdType
{

	E_CMD_TrainInit = 0;

	E_CMD_LHandTPose = 1;

	E_CMD_LHandVibrate = 2;

	E_CMD_RHandTPose = 3;

	E_CMD_RHandVibrate = 4;

	E_CMD_MocapTPose = 5;

	E_CMD_MocapShutDown = 6;

	E_CMD_OnlineUsrList = 7;

	E_CMD_OnlineDeviceList = 8;
}


message SensorStrategy
{

	bool bUse = 1;

	bool bLocal = 2;
}


message Strategy
{
	repeated SensorStrategy sensor = 1;
}


message User
{

	uint32 nDeviceId = 1;

	uint32 nUsrId = 2;

	Strategy usrStrat = 3;
}


message TrainParams
{

	repeated User usr = 1;

	uint64 nBaseTimeMs = 2;
}


message OnlineUser
{

	repeated uint32 nOnlineUserId = 1;
}


message OnlineDevice
{
	repeated uint32 nOnlineDeviceId = 1;
}


message COMMAND
{

	uint32 nToken = 1;

	uint32 nCode = 2;

	ECmdType eType = 3;

	google.protobuf.Any param = 4;
}

message DATA
{

	fixed32 nDataLen = 1;

	uint64 nSendTime = 2;

	google.protobuf.Any data = 3;
}

该proto文件包含了任意类Any,枚举类型以及数组类型repeated等使用,随后选中该proto文件,右键点击quick gen protobuf here则会生成demo.java文件。
最后编写测试类,验证是否可以通过demo.java实现数据的序列化和反序列化。

    public static void main(String[] args) {
        Monitor.SensorStrategy.Builder sensorStrategyBuilder1 = Monitor.SensorStrategy.newBuilder();
        sensorStrategyBuilder1.setBUse(true).setBLocal(false);
        Monitor.SensorStrategy.Builder sensorStrategyBuilder2 = Monitor.SensorStrategy.newBuilder();
        sensorStrategyBuilder2.setBUse(true).setBLocal(true);
        Monitor.SensorStrategy.Builder sensorStrategyBuilder3 = Monitor.SensorStrategy.newBuilder();
        sensorStrategyBuilder3.setBUse(false);
        Monitor.SensorStrategy.Builder sensorStrategyBuilder4 = Monitor.SensorStrategy.newBuilder();
        sensorStrategyBuilder4.setBUse(true).setBLocal(true);

        Monitor.Strategy.Builder strategyBuilder = Monitor.Strategy.newBuilder();

        strategyBuilder.addSensor(0,sensorStrategyBuilder2);

        strategyBuilder.addSensor(1,sensorStrategyBuilder3);

        strategyBuilder.addSensor(2,sensorStrategyBuilder1);

        strategyBuilder.addSensor(3,sensorStrategyBuilder4);

        Monitor.User.Builder userBuilder = Monitor.User.newBuilder();
        userBuilder.setNDeviceId(1).setNUsrId(7).setUsrStrat(strategyBuilder);


        Monitor.TrainParams.Builder trainBuilder = Monitor.TrainParams.newBuilder();
        trainBuilder.addUsr(userBuilder).setNBaseTimeMs(5000);

        Monitor.COMMAND.Builder commandBuilder = Monitor.COMMAND.newBuilder();

        commandBuilder.setNToken(5454).setNCode(0x01).setEType(E_CMD_TrainInit).setParam(Any.pack(trainBuilder.build()));


        Monitor.DATA.Builder dataBuilder = Monitor.DATA.newBuilder();
        dataBuilder.setNSendTime(CommonUtils.getTimeStamp());
        //设值的时候数据长度放在最后!!!因为会变化
        dataBuilder.setData(Any.pack(commandBuilder.build())).setNSendTime(10000).setNDataLen(dataBuilder.build().toByteArray().length);

        //序列化发送
        byte[] bytes = dataBuilder.build().toByteArray();
        System.out.println("序列化后的数据:" + Arrays.toString(bytes)+",字节个数:"+bytes.length);

        //5.反序列化
        try {
            //创建UDP客户端
            DatagramSocket socket = new DatagramSocket();
            //创建数据发送包
            DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.58.253"),15682);
            //消息发送
            while (true) {
                Thread.sleep(2000);
                socket.send(packet);

                Monitor.DATA parseFrom = Monitor.DATA.parseFrom(bytes);
                System.out.println("DATA.nDataLen= "+ parseFrom.getNDataLen());
                System.out.println("DATA.nSendTime= "+ parseFrom.getNSendTime());


                Monitor.COMMAND unpackCommand = parseFrom.getData().unpack(Monitor.COMMAND.class);
                System.out.println("COMMAND.nCode= "+unpackCommand.getNCode());
                System.out.println("COMMAND.eType= "+unpackCommand.getEType());
                System.out.println("COMMAND.nToken= "+unpackCommand.getNToken());

                Monitor.TrainParams unpackTrain = unpackCommand.getParam().unpack(Monitor.TrainParams.class);
                System.out.println("u"+unpackTrain.getNBaseTimeMs());


            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

最终测试结果如下:
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Java使用protobuf需要以下步骤: 1. 下载protobuf的jar包和编译器protoc.exe。 2. 编写.proto文件,定义数据结构和消息格式。 3. 使用protoc.exe编译.proto文件,生成Java代码。 4. 在Java项目引入protobuf的jar包和生成的Java代码。 5. 使用生成的Java代码进行序列化和反序列化操作。 具体步骤如下: 1. 下载protobuf的jar包和编译器protoc.exe,并将它们放在项目。 2. 编写.proto文件,定义数据结构和消息格式。例如: ``` syntax = "proto3"; package com.example.proto; message Person { string name = 1; int32 age = 2; repeated string phone_numbers = 3; } ``` 3. 使用protoc.exe编译.proto文件,生成Java代码。在命令行执行以下命令: ``` protoc --java_out=./src/main/java ./src/main/proto/person.proto ``` 这将在src/main/java/com/example/proto目录下生成Person.java文件。 4. 在Java项目引入protobuf的jar包和生成的Java代码。例如,在Maven项目,可以在pom.xml文件添加以下依赖: ``` <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.17.3</version> </dependency> ``` 5. 使用生成的Java代码进行序列化和反序列化操作。例如: ``` Person person = Person.newBuilder() .setName("Alice") .setAge(30) .addPhoneNumbers("123456789") .addPhoneNumbers("987654321") .build(); byte[] data = person.toByteArray(); // 反序列化 Person newPerson = Person.parseFrom(data); ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值