java原生序列化可以跨语言吗_使用protobuf实现跨语言序列化 Java和Python实例

使用protobuf实现跨语言序列化 Java和Python实例

首先下载安装protoc

对于OS X可以通过brew直接安装 brew install protobuf

安装完可以通过protoc --version查看版本信息

创建proto文件-带Any类型的版本

带Any类型的只能导出pb2类型的Python文件,没法导出Python3 的版本,暂时不知道如何解决

Any类型的字段可以在java中实现泛型的功能

MessageDto.proto

syntax = "proto3";

import "google/protobuf/any.proto";

message MessageDto {

string action=1;

int32 statte=2;

google.protobuf.Any data=3;

}

RpcCmd.proto

syntax = "proto3";

import "MessageDto.proto";

message RpcCmd {

MessageDto message=1;

string randomKey=2;

string remoteAddressKey=3;

}

Point2PointMessage.proto

syntax = "proto3";

message Point2PointMessage {

string targetAddressKey;

string message;

}

BytesData.proto

syntax = "proto3";

message BytesData {

bytes content=1;

}

导出相应的对象定义文件

Python版

protoc --python_out=./gen_pb2 RpcCmd.proto MessageDto.proto Point2PointMessage.proto BytesData.proto

生成的文件名为XXX_pb2.py

Java版

protoc --java_out=./gen_java RpcCmd.proto MessageDto.proto Point2PointMessage.proto BytesData.proto

生成的文件名为XXXOuterClass.java

在Python中使用

首先要导入生成的文件,放到自己喜欢的包下,然后修改导入包的地址,比如RpcCmd_pb2.py中修改

import com.tony.proto.py2.MessageDto_pb2 as MessageDto__pb2

然后开始使用

from com.tony.proto.py2 import RpcCmd_pb2, Point2PointMessage_pb2, BytesData_pb2, MessageDto_pb2

def serialize_to_file(file_path):

p2p_msg = Point2PointMessage_pb2.Point2PointMessage()

p2p_msg.message = "Hello, p2p from python"

p2p_msg.targetAddressKey = "/127.0.0.1:38211"

# bytes_data = BytesData_pb2.BytesData()

# bytes_data.content = b"Hello, bytes data from python"

rpc_cmd = RpcCmd_pb2.RpcCmd()

rpc_cmd.randomKey = "random-key-key-random"

rpc_cmd.remoteAddressKey = "/127.0.0.1:1234"

rpc_cmd.message.action = "p2p"

rpc_cmd.message.state = 100

rpc_cmd.message.data.Pack(p2p_msg)

# rpc_cmd.message.data.Pack(bytes_data)

bytes_write = rpc_cmd.SerializeToString()

fw = open(file_path, mode="wb")

fw.write(bytes_write)

fw.flush()

fw.close()

print("write bytes to file:", bytes_write)

def deserialize_from_file(file_path):

fo = open(file_path, mode="rb")

bytes_read = fo.read()

fo.close()

print("read bytes from file:", bytes_read)

rpc_cmd = RpcCmd_pb2.RpcCmd()

rpc_cmd.ParseFromString(bytes_read)

print(rpc_cmd)

p2p_msg = Point2PointMessage_pb2.Point2PointMessage()

# bytes_data = BytesData_pb2.BytesData()

# rpc_cmd.message.data.Unpack(bytes_data)

rpc_cmd.message.data.Unpack(p2p_msg)

print("msg_content:", p2p_msg.message)

print("msg_target:", p2p_msg.targetAddressKey)

# print("bytes_data:", str(bytes_data.content, 'utf-8'))

if __name__ == "__main__":

serialize_file_path = "/trans-data-pb2.dat"

serialize_to_file(serialize_file_path)

deserialize_from_file(serialize_file_path)

执行结果如下,可以将bytes_data相关的注释取消同时注释掉p2p_msg相关的测试BytesData类型的序列化和反序列化

write bytes to file: b'\n]\n\x03p2p\x10d\x1aT\n&type.googleapis.com/Point2PointMessage\x12*\n\x10/127.0.0.1:38211\x12\x16Hello, p2p from python\x12\x15random-key-key-random\x1a\x0f/127.0.0.1:1234'

read bytes from file: b'\n]\n\x03p2p\x10d\x1aT\n&type.googleapis.com/Point2PointMessage\x12*\n\x10/127.0.0.1:38211\x12\x16Hello, p2p from python\x12\x15random-key-key-random\x1a\x0f/127.0.0.1:1234'

message {

action: "p2p"

state: 100

data {

type_url: "type.googleapis.com/Point2PointMessage"

value: "\n\020/127.0.0.1:38211\022\026Hello, p2p from python"

}

}

randomKey: "random-key-key-random"

remoteAddressKey: "/127.0.0.1:1234"

msg_content: Hello, p2p from python

msg_target: /127.0.0.1:38211

在Java中使用

同样导入到喜欢的包下,修改对应的包名即可

@Slf4j

public class ProtobufSerializeDemo {

@Test

public void serializeToFile() throws Exception {

Point2PointMessageOuterClass.Point2PointMessage.Builder p2pMsgBuilder = Point2PointMessageOuterClass.Point2PointMessage.newBuilder();

p2pMsgBuilder.setTargetAddressKey("/127.0.0.1:1233");

p2pMsgBuilder.setMessage("hello from java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值