从字节数组中识别 ProtoBuf class
Identify ProtoBuf class from byte array
我正在编写一个处理两个原型消息的程序,我需要处理从不同源发送的 byte[],这些源发送 foo 消息或 bar 消息。因为我无法弄清楚它属于哪条消息,所以我使用 Any Class (与 protobuf 一起提供)来解析字节数组和
找到它属于哪个 class,但遇到编译时错误。有没有其他方法可以用来检测我将来是否添加更多原型消息 classes?
//Foo.proto
syntax = "proto3";
option java_outer_classname = "FooProto";
message Foo {
int32 a = 1;
}
和第二个原型
//Bar.proto
syntax = "proto3";
option java_outer_classname = "BarProto";
message Bar {
int32 b = 1;
}
代码:
Any anyEvent = Any.parseFrom(protoBytes);
if (any.is(Foo.class)
{
Foo foo = any.unpack(Foo.class);
...
} else {
Bar bar = any.unpack(Bar.class);
...
}
尝试调用 any.is() 时 if 语句出错:
The method is(Class< T>) in the type Any is not applicable for the arguments (Class< Foo>)
Any
不代表"any";这意味着 "a type serialized via Any"。如果你没有 store 它与 Any
: 你不能 decode 通过 Any
.
这里的关键点是 protobuf 不在消息负载中包含类型元数据。如果您有 BLOB,您通常无法知道消息类型是什么。 Any
通过在包装消息 中对消息类型 进行编码来解决此问题,但您不会在此处使用它。
如果您的设计是 API 接受两种不同的非 Any
消息类型,而事先不知道它是哪种消息类型:您的设计可能很糟糕。因为 不适用于 protobuf 。在网络上,Foo
与 a=42
和 Bar
与 b=42
之间 几乎没有区别;有效载荷 相同:
Foo
和 a=42
是字节数 08 2A
; Bar
和 b=42
是字节 08 2A
。 08
表示 "field 1, encoded as a varint",2A
是原始值为 42 的 varint。
更好的设计可能是包装消息特定于您的场景:
message RootMessage {
oneof test_oneof {
Foo foo = 1;
Bar bar = 2;
}
}
这为 Any
的工作方式添加了一个包装层 与 相似,但效率更高 - 它只知道如何将已知类型区分为整数,而不是而不是必须处理所有可能的类型(作为根类型名称)。
我正在编写一个处理两个原型消息的程序,我需要处理从不同源发送的 byte[],这些源发送 foo 消息或 bar 消息。因为我无法弄清楚它属于哪条消息,所以我使用 Any Class (与 protobuf 一起提供)来解析字节数组和 找到它属于哪个 class,但遇到编译时错误。有没有其他方法可以用来检测我将来是否添加更多原型消息 classes?
//Foo.proto
syntax = "proto3";
option java_outer_classname = "FooProto";
message Foo {
int32 a = 1;
}
和第二个原型
//Bar.proto
syntax = "proto3";
option java_outer_classname = "BarProto";
message Bar {
int32 b = 1;
}
代码:
Any anyEvent = Any.parseFrom(protoBytes);
if (any.is(Foo.class)
{
Foo foo = any.unpack(Foo.class);
...
} else {
Bar bar = any.unpack(Bar.class);
...
}
尝试调用 any.is() 时 if 语句出错:
The method is(Class< T>) in the type Any is not applicable for the arguments (Class< Foo>)
Any
不代表"any";这意味着 "a type serialized via Any"。如果你没有 store 它与 Any
: 你不能 decode 通过 Any
.
这里的关键点是 protobuf 不在消息负载中包含类型元数据。如果您有 BLOB,您通常无法知道消息类型是什么。 Any
通过在包装消息 中对消息类型 进行编码来解决此问题,但您不会在此处使用它。
如果您的设计是 API 接受两种不同的非 Any
消息类型,而事先不知道它是哪种消息类型:您的设计可能很糟糕。因为 不适用于 protobuf 。在网络上,Foo
与 a=42
和 Bar
与 b=42
之间 几乎没有区别;有效载荷 相同:
Foo
和 a=42
是字节数 08 2A
; Bar
和 b=42
是字节 08 2A
。 08
表示 "field 1, encoded as a varint",2A
是原始值为 42 的 varint。
更好的设计可能是包装消息特定于您的场景:
message RootMessage {
oneof test_oneof {
Foo foo = 1;
Bar bar = 2;
}
}
这为 Any
的工作方式添加了一个包装层 与 相似,但效率更高 - 它只知道如何将已知类型区分为整数,而不是而不是必须处理所有可能的类型(作为根类型名称)。