如何在Ruby和Java之间序列化/解析protobuf对象?

时间:2015-08-19 20:33:09

标签: java ruby rabbitmq protocol-buffers

在ruby中序列化protobuf对象和在Java中解析的正确方法是什么?这是为了进行自动化测试,我们正在Rabbit队列中监听此消息。

Publisher(Ruby):

protoNew = Protobuf::Request.new
protoNew.request = request
protoNew.id = id.to_i
protoNew.authentication = authentication

return protoNew.serialize_to_string

消费者(Java):

    @Override
    public void onMessage(Message message, Channel channel) 
    {
        ProtoRequest protoRequest;
        try {
            protoRequest = ProtoRequest.parseFrom(message.getBody());
        } catch (InvalidProtocolBufferException e1) {
            logger.error("Error parsing protobuf", e1);
        } 

以下是我看到的错误:

  

解析protobuf时出错:com.google.protobuf.InvalidProtocolBufferException:协议消息end-group标记与期望标记不匹配。           at com.google.protobuf.InvalidProtocolBufferException.invalidEndTag(InvalidProtocolBufferException.java:94)[protobuf-java-2.6.1.jar:]           在com.google.protobuf.CodedInputStream.checkLastTagWas(CodedInputStream.java:174)[protobuf-java-2.6.1.jar:]           在com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:139)[protobuf-java-2.6.1.jar:]           在com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:168)[protobuf-java-2.6.1.jar:]           在com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:180)[protobuf-java-2.6.1.jar:]           在com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:185)[protobuf-java-2.6.1.jar:]           在com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49)[protobuf-java-2.6.1.jar:]

1 个答案:

答案 0 :(得分:1)

目前尚不清楚如何打包protoNew.serialize_to_string输出,使其成为Java代码的JMS消息的内容。我猜有些东西因为字符编码而变得混乱。

作为解决方法,您可以对protoNew.serialize_to_string的二进制输出执行Base 64编码,并在Java端执行Base 64解码。

require "base64"
...
return Base64.encode64 protoNew.serialize_to_string

在Java端,

import org.apache.commons.codec.binary.Base64;
...
protoRequest = ProtoRequest.parseFrom(Base64.decodeBase64(message.getBody()))

上述解决方案的一个不好之处在于,与纯二进制形式相比,它将导致更大的有效负载大小。

PS:请注意,如果我将person.serialize_to_string的输出写入Ruby端的文件,并在Java上读取该文件,它似乎工作正常

f = File.open("data.dat", "wb")
f << person.serialize_to_string
f.close