java调用protobuf

本文介绍了protobuf的原理、特点及其在项目中如何简单快速地应用,对比XML和JSON,阐述了protobuf在数据传输效率和安全性方面的优势,并通过实例展示了如何使用protobuf进行对象序列化与反序列化。
Python3.8

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

    protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。---摘自百度百科。

    从上面可以看出,protobuf其实是一种传输协议,这个跟thrift有很大不同。thrift是Facebook开源的一整套的RPC方案,但是它却总是被拿来跟protobuf做对比,这个有很大的误导,正确的说是,thrift里面不仅仅包含了传输协议。因此,跟protobuf相比较的应该xml或者是json。我们可以来简单的说一下,protobuf相较于xml或者json的区别,protobuf是基于将数据采用二进制来序列化的,而xml或者json则是基于文本数据的,现在高下立判,protobuf比xml或者说json更加高效和安全,而且序列化反序列化方便。

    之前,看protobuf总是一副高大上的样子,让人望而生畏。最近需要写个项目,采用udp去跟另一边用.net开发的服务通讯,所以采用protobuf作为两边之间通信协议(对象序列化反序列化协议),于是就写了下demo。发觉其实非常简单,我们如果用protobuf更多的只需要关注底层的传输就OK了,剩下的序列化反序列化它其实已经说好了。

    用java写最简单的protobuf只需要两件东西,一件是将proto文件(protobuf独有的用来规定各种不同语言间统一数据描述规范)转成java实体类的程序(我在windows下用protoc.exe文件,这个文件code.google.com有编译好的),另一个就是java的protobuf 实现的jar包了。

   <dependency>
          <groupId>com.google.protobuf</groupId>
          <artifactId>protobuf-java</artifactId>
          <version>2.5.0</version>
   </dependency>
接下来在写proto文件

package protobuf;
option java_package = "com.xxx.simpleProtobuf";
option java_outer_classname = "LogMessageProtobuf";
message LogMessage  {
  required int32 ID = 1;
  required string Url = 2;
  required string message = 3;
}

定义好了之后,需要用protoc.exe 翻译成java文件,记住protoc跟java的接口jar包的版本要一致。

在命令行运行protoc  --java_out=./   LogMessageProtobuf.proto

接下来就可以在同一个目录下看到com/xxx/simpleProtobuf里面的 LogMessageProtobuf.java文件

import com.google.protobuf.InvalidProtocolBufferException;

/**
 * Created by lsz on 2014/7/18.
 */
public class ProtobufDemo{
    public static void main(String[] args) throws InvalidProtocolBufferException {
        LogMessageProtobuf.LogMessage  logMsg = LogMessageProtobuf.LogMessage.newBuilder()
						 .setID(1)
						.setUrl("http://www.xxxx.com")
					       .setMessage("xxxx").build();
        System.out.println(logMsg);
        byte[] bs = tb.toByteArray();
        LogMessageProtobuf.LogMessage  logMsgFromBytes = LogMessageProtobuf.LogMessage.parseFrom(bs);
        System.out.println(logMsgFromBytes);



    }
}


运行成可以看到logMsg跟logMsgFromBytes的内容是一样的,根据上面的例子,我们会发现,真正保存这个对象数据的就是bs这个字节数组,没有其他的内容,那我们是不是可以通过其他途径去传输这个byte数组,让其他的地方也可以得到这个数据对象呢。




您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

### JavaProtobuf 的使用教程 #### 1. 安装与配置 为了在 Java 中使用 Protocol Buffers (Protobuf),需要先安装 `protoc` 编译器并将它加入环境变量路径。接着,在项目的构建工具(如 Maven 或 Gradle)中引入依赖项。 Maven 配置如下: ```xml <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.21.7</version> </dependency> ``` Gradle 配置如下: ```gradle implementation 'com.google.protobuf:protobuf-java:3.21.7' ``` --- #### 2. 创建 `.proto` 文件 `.proto` 文件用于定义消息结构。以下是一个简单的例子: ```proto syntax = "proto3"; option java_package = "com.example.protos"; option java_outer_classname = "AddressBookProtos"; // 明确指定生成的外层类名[^2] message Person { string name = 1; int32 id = 2; string email = 3; enum PhoneType { // 枚举类型的定义[^5] MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { // 嵌套的消息类型 string number = 1; PhoneType type = 2; } repeated PhoneNumber phones = 4; // 可重复字段表示列表 } // 外部容器消息 message AddressBook { repeated Person people = 1; } ``` --- #### 3. 使用 `protoc` 编译 `.proto` 文件 运行以下命令将 `.proto` 文件编译成 Java 类: ```bash protoc --java_out=./src/main/java ./path/to/addressbook.proto ``` 这将在指定目录下生成对应的 Java 文件,例如 `AddressBookProtos.java`。该文件包含了所有的消息类及其嵌套类。 --- #### 4. 序列化与反序列化操作 以下是基于生成的 Java 类实现序列化和反序列化的示例代码。 ##### (1)序列化数据为字节数组 ```java import com.example.protos.AddressBookProtos.Person; import com.example.protos.AddressBookProtos.PhoneNumber; import com.example.protos.AddressBookProtos.AddressBook; public class ProtoExample { public static void main(String[] args) throws Exception { // 创建一个Person实例 Person.Builder personBuilder = Person.newBuilder(); personBuilder.setName("Alice"); personBuilder.setId(123); personBuilder.setEmail("alice@example.com"); // 添加电话号码 PhoneNumber phoneNumber = PhoneNumber.newBuilder() .setNumber("555-1234") .setType(Person.PhoneType.MOBILE) .build(); personBuilder.addPhones(phoneNumber); // 将Person添加到AddressBook AddressBook addressBook = AddressBook.newBuilder().addPeople(personBuilder.build()).build(); // 序列化为字节数组 byte[] data = addressBook.toByteArray(); // 调用toByteArray方法完成序列化[^1] System.out.println("Serialized Data Length: " + data.length); } } ``` ##### (2)从字节数组反序列化回对象 ```java import com.example.protos.AddressBookProtos.AddressBook; public class DeserializeExample { public static void main(String[] args) throws Exception { // 假设data是从某个地方获得的字节数组 byte[] data = ... ; // 反序列化为AddressBook对象 AddressBook addressBook = AddressBook.parseFrom(data); // 调用parseFrom方法完成反序列化 // 输出解析后的信息 for (Person person : addressBook.getPeopleList()) { System.out.println("Name: " + person.getName()); System.out.println("ID: " + person.getId()); System.out.println("Email: " + person.getEmail()); for (PhoneNumber phone : person.getPhonesList()) { System.out.println("Phone Number: " + phone.getNumber() + ", Type: " + phone.getType()); } } } } ``` --- #### 5. JSON 和 Map 结构转换 除了二进制格式,Protobuf 支持与其他常见数据格式(如 JSON、Map)之间的相互转换。 ##### (1)JSON 转换 可以利用 Google 提供的 `JsonFormat` 工具类进行 JSON 格式的转换。 ```java import com.google.protobuf.util.JsonFormat; public class JsonConversionExample { public static void main(String[] args) throws Exception { String jsonString = "{\"people\":[{\"id\":1,\"name\":\"Bob\",\"email\":\"bob@example.com\"}]}"; // 解析JSON字符串为AddressBook对象 AddressBook addressBook = AddressBook.getDefaultInstance(); JsonFormat.parser().merge(jsonString, addressBook.toBuilder()); // 打印结果 System.out.println(addressBook.toString()); } } ``` ##### (2)Map 转换 通过第三方库(如 Gson),可将 Protobuf 对象转化为 Map 形式[^3]。 ```java Gson gson = new Gson(); Map<String, Object> map = gson.fromJson("{\"key\":\"value\"}", new TypeToken<Map<String, Object>>() {}.getType()); System.out.println(map); ``` --- #### 总结 以上展示了如何在 Java 中使用 Protobuf 进行消息定义、编译以及序列化/反序列化操作。此外还介绍了 JSON 和 Map 的转换方式,便于开发者灵活处理不同场景下的需求。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值