当前位置: 首页 > 知识库问答 >
问题:

有没有办法在不知道其节俭类型的情况下将原始字节[]反序列化回节俭对象?

司马彦
2023-03-14

我正在运行一个项目,需要

  • 不同编程语言(主要是java、c)之间的交互通信

Thrift完全符合这些标准,尽管我们不需要它的RPC函数。我们将通过MQ发送/接收序列化的thrift数据。序列化对象非常简单。然而,在反序列化方面,我们不能这样做:

byte[] data = recv();
Object object = TDeserializer.deserialize(data);
if (object instanceof TypeA) {
    TypeA a = (TypeA) object;
} else if (object instanceof TypeB) {
    TypeB b = (TypeB) object;
}

似乎我们必须准确地告诉thrift需要反序列化为哪个结构,比如:

byte[] data = recv();
TypeA a;
TDeserializer.deserialize(a, data);

只是想知道是否有办法将原始数据反序列化为thrift对象,而不知道其确切类型。

谢谢!!

共有1个答案

柯骏
2023-03-14

Thrift序列化消息本身不包含类型信息,所以反序列化程序必须知道消息数据类型。然而,可以将所有必要的数据类型封装到union中。

节俭html" target="_blank">代码:

union Message {
    1: TypeA a;
    2: TypeB b;
}

反序列化代码:

byte[] data = recv();
Message msg;
TDeserializer.deserialize(msg, data);
<find out message type with msg.getSetField()>

如果需要添加新的消息类型,只需将另一个字段添加到union中即可。如果不接触旧的字段ID,则将保留向后兼容性:

union Message {
    1: TypeA a;
    2: TypeB b;
    3: TypeC c; <-- OK
}

您将能够接收来自老制作人的消息(他们永远不会发送C类消息),也不会向老消费者发送A类消息。如果您向不知道字段#3的消费者发送TypeC消息,它将得到异常。

这种方法的最大优点是类型信息非常紧凑。如果使用CompactProtocol,则在大多数情况下,类型信息只会额外占用1个字节(如果消息中的字段ID小于127)。

小心,如果更改字段ID,将失去向后兼容性。例如:

union Message {
    1: TypeA a;
    2: TypeC c; <-- Wrong
    3: TypeB b; <-- Wrong
    4: TypeD d; <-- OK
}
 类似资料:
  • 我不能在使用C Glib序列化的Java节俭对象中反序列化。我的序列化代码如下(我在这里提出问题后提出的解决方案): 发送和接收的消息长度相同。但不知何故,在Java端,我不能复制对象。 可能有人面临过类似的问题? UPD: null 在发送到Kafka之前,对相同的tbuffer->buf连续进行了两次十六进制转储。看起来缓冲区在发送前包含错误的数据:

  • 在我的应用程序中,有几个组件将生成各种不同类型的特定于应用程序的事件。这些事件将发布到代理并传递给N个客户端。其中一些客户端是我的服务器端应用程序中的其他Java类,但主要消费者是我的基于javascript的WebUI。 到目前为止,我目前的方法是定义一个抽象事件基类来封装一些公共字段,然后为每个事件实现一个特定的事件类。 这一直工作正常,只是现在我需要在javascript和java端维护事件

  • 我计划使用kafka作为事件来源的持久日志,目前正在研究不同的序列化选项。我目前的重点是使用thrift对我将存储在Kafka中的消息进行序列化和反序列化。

  • 我使用EclipseMars(M1)作为我的IDE。今天,我使用Apache Thrift 0.9.2(最新稳定版本)为Android项目生成了我的服务的Java代码。这个版本(unlke版本0.9.1)使用来自javax的“生成”注释。注释包,用于添加一些可提取的文档。它在每个生成的类之前添加一行,如下所示: @已生成(value=“节俭编译器自动生成(0.9.2)”,日期=“2014-11-3

  • 问题内容: 在Java中,是否有一种方法(在运行时)获取定义了特定类的字节码? 换句话说,有没有一种方法可以获取在加载特定类时传递给数组的数组?我看到已经声明了此方法,因此似乎无法创建一个自定义类来拦截类定义。 过去,我曾使用该类通过该方法获取字节码,但我希望使用更规范的解决方案。 问题答案: 这是如何实现代理的说明

  • 我无法配置Spark SQL,使我能够访问Spark Thrift服务器中的配置单元表(不使用JDBC,而是从Spark本地) 错误XJ040:无法使用类加载器sun.misc.launcher$AppClassLoader@1B4FB997启动数据库“/home/user/spark-2.4.0-bin-hadoop2.7/mistastore_db” 错误XSDB6:另一个Derby实例可能已