我无法在使用C GLib序列化的Java Thrift对象中反序列化。 我的序列化代码如下(我在问题here后提出的解决方案):
ThriftMemoryBuffer* tbuffer = g_object_new(THRIFT_TYPE_MEMORY_BUFFER,
"buf_size", 2048, NULL);
ThriftTransport *transport = NULL;
ThriftProtocol* protocol = NULL;
GError* error = NULL;
if (tbuffer) {
transport = THRIFT_TRANSPORT(tbuffer);
thrift_transport_open(transport, &error);
protocol =
THRIFT_PROTOCOL(
g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));
if (protocol) {
ExceptionData* exception_data = g_object_new(TYPE_EXCEPTION_DATA, "ex_sign",
exception_signature, "cl_sign", class_signature, "caught",
catch_method != NULL,
NULL);
if (exception_data) {
ThriftStructClass* cls = THRIFT_STRUCT_CLASS(EXCEPTION_DATA_GET_CLASS(exception_data));
int write_len = cls->write(exception_data, protocol, &error);
if(tbuffer->buf != NULL) {
printf("Write len %i bytes\n", write_len);
printf("Data sending: %s, %s, %b \n", exception_data->ex_sign, exception_data->cl_sign, exception_data->caught);
send_kafka_message((const void *)tbuffer->buf, write_len);
}
g_object_unref(exception_data);
}
g_object_unref(protocol);
}
if (thrift_transport_is_open(transport)) {
thrift_transport_close(transport, &error);
}
g_object_unref(tbuffer);
}
Java中的反序列化代码:
TDeserializer deserializer = new TDeserializer();
ExceptionData ex = new ExceptionData();
try {
byte[] binData = tuple.getBinary(0);
_logger.info("Bin data length: " + binData.length);
_logger.info("HEX data: " + DatatypeConverter.printHexBinary(binData));
deserializer.deserialize(ex, binData);
} catch (TException e) {
_logger.error(e);
}
_logger.info("Deserialized object: " + ex);
它始终失败,例外情况类似于:
org.apache.thrift.protocol.TProtocolException: Required field 'caught' was not found in serialized data!
My Thrift计划是:
struct ExceptionData {
1: required string ex_sign, // exception signature
2: required string cl_sign, // class signature where exception was thrown
3: required bool caught // whether exception was caught or not
}
发送和接收的消息长度相同。但不知何故,在Java方面,我无法重现对象。
可能有人遇到过类似的问题吗?UPD:
示例输出:
ExceptionData("Ljava/lang/ClassNotFoundException;", "Ljava/net/URLClassLoader;", true)
HEX data: 40890DE0297F00004C000000800000000100000000000000010000000000000000000000000000000000000000000000007E0DE0297F00000100000000000000000000000000000090D900E0
HEX data(1): 00880D109D7F00004E000000800000000100000000000000010000000000000000000000000000000000000000000000007E0D109D7F000001000000000000000000000000000000507F0D109D7F
HEX data(2): 00880D4CF57F00004E000000800000000100000000000000010000000000000000000000000000000000000000000000007E0D4CF57F000001000000000000000000000000000000507F0D4CF57F
我注意到上面的输出有些奇怪的事情:
我尝试序列化 - 反序列化相同的对象仅使用Java ,这是示例输出:
ExceptionData("Ljava/lang/ClassNotFoundException;", "Ljava/net/URLClassLoader;", true)
HEX data: 0B0001000000224C6A6176612F6C616E672F436C6173734E6F74466F756E64457863657074696F6E3B0B0002000000194C6A6176612F6E65742F55524C436C6173734C6F616465723B0200030100
如果我只使用Java对象正确地序列化 - 反序列化,并且HEX输出对于相同的输入数据是相同的
UPD2:
在发送到kafka之前,将相同tbuffer-> buf的两个连续十六进制转储组成。在发送之前看起来缓冲区包含错误的数据:
call 1 buf:
0000 00 88 0d 2c ce 7f 00 00 4e 00 00 00 80 00 00 00 ...,....N.......
0010 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030 00 7e 0d 2c ce 7f 00 00 01 00 00 00 00 00 00 00 .~.,............
0040 00 00 00 00 00 00 00 00 50 e2 00 2c ce 7f ........P..,..
call 2 buf:
0000 80 88 0d b8 08 7f 00 00 4e 00 00 00 80 00 00 00 ........N.......
0010 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030 00 e1 00 b8 08 7f 00 00 01 00 00 00 00 00 00 00 ................
0040 00 00 00 00 00 00 00 00 20 88 0d b8 08 7f ........ .....
答案 0 :(得分:2)
最后我发现错误在哪里。序列化数据存储在 tbuffer-> buf->数据而不是tbuffer-> buf中。缓冲区长度存储在 tbuffer-> buf-> len 。
所以,最终的工作代码是:
$result = mysqli_query($con,$query);
return mysqli_query($con, $query);