【问题标题】:Protobuf DynamicMessage parseProtobuf DynamicMessage 解析
【发布时间】:2021-07-28 09:56:49
【问题描述】:

我正在尝试使用 java 解析通用 protobuf 消息。它适用于 Oneof 或简单类型,但对于 Any 我有问题。

private static DynamicMessage parseData(byte[] data) throws IOException, Descriptors.DescriptorValidationException {
    DescriptorProtos.FileDescriptorSet set = DescriptorProtos.FileDescriptorSet.parseFrom(new FileInputStream("file1.desc");
    DescriptorProtos.FileDescriptorSet any = DescriptorProtos.FileDescriptorSet.parseFrom(new FileInputStream("any.desc"));
    var anyDesc = Descriptors.FileDescriptor.buildFrom(any.getFile(0), new Descriptors.FileDescriptor[] {});
    Descriptors.FileDescriptor
        md = Descriptors.FileDescriptor.buildFrom(set.getFile(0), new Descriptors.FileDescriptor[] {anyDesc});
    Descriptors.Descriptor messageType = md.getMessageTypes().get(0);
    return DynamicMessage.parseFrom(messageType, data);
}

我的架构

syntax = "proto3";

import "google/protobuf/any.proto";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
  google.protobuf.Any test = 4;
}

message Test2 {
  string one = 1;
  string two = 2;
  string three = 3;
}

message Test3 {
  string one = 1;
}

此测试代码有效,我收到消息

query: "sad"
page_number: 1
result_per_page: 123
test {
  type_url: "type.googleapis.com/Test2"
  value: "\n\003one\022\003two\032\005three"
}

这就是问题所在。 Any 字段未解析。 我怎样才能做到这一点?

我需要通过type_url 名称解析任何字段。但是我没有地方可以做。

附:遍历生成的 dynamicMessage 并检查字段是否为 Any 然后解析它似乎不是一个好主意,因为我将嵌套任何。

我的主要目标是通过 protobuf 模式解析消息并转换为 json。架构会改变,所以我不能使用生成类的方法。

这是测试代码。

【问题讨论】:

  • 您必须(递归地)遍历消息。 any 消息是嵌入在另一条消息中的 protobuf。因此,当遇到时,通常您会查找 type_url 以查找描述符,或者,如果动态解码,则您需要再次开始解析,因为您发现了一个全新的 protobuf 消息......因为@987654331 @ 可以嵌套,你需要重复直到你解码所有的海龟。

标签: java protocol-buffers proto protobuf-java


【解决方案1】:

用递归方法解决。我浏览所有字段并检查是否有任何字段并通过 type_url 解析它

【讨论】:

    猜你喜欢
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    相关资源
    最近更新 更多