Thrift是如何实现序死化与反序列化的,在IDL文件中,更改IDL文件中的变量序号或者[使用默认序号的情况下,新增变量时,将新增的变量不放在IDL文件的结尾,均会导致Thrift文件的反序列后无法做到向后兼容],我们只有理解Thrift是如何实现序列化的,才能了解这种现象产生的原因,才能把代码写的更让人放心
关于Thrift域的版本号的定义可以在http://thrift.apache.org/static/files/thrift-20070401.pdf这篇文章中找到说定义
1
2
3
4
5
6
7
8
|
Versioning
in
Thrift
is
implemented via field identifiers.
The field header
for
every member of a
struct
in
Thrift
is
encoded with a unique field identifier. The combination of
this
field identifier and its type specifier
is
used to
uniquely identify the field. The Thrift definition language
supports automatic assignment of field identifiers,
but it
is
good programming practice to always explicitly
specify field identifiers.
|
翻译过来,大概意思就是Thrift中每个域都有一个版本号,这个版本号是由属性的数字序号 + 属性的类型来确定的
一个简单的Thrift文件
1
2
3
4
|
struct
Test {
1 : required i32 key;
2 : required
string
value;
}
|
执行
1
|
thrift -gen java Test.thrift
|
将thrift文件转换成java源文件,在此不列出详细的源文件内容,只列出与序列化与反序列化相关的代码
序列化,实际上就是write,如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//http://www.aiprograming.com/b/pengpeng/24<br>public void write(org.apache.thrift.protocol.TProtocol oprot, Test struct) throws org.apache.thrift.TException {
struct
.validate();
oprot.writeStructBegin(STRUCT_DESC);
oprot.writeFieldBegin(KEY_FIELD_DESC);
oprot.writeI32(
struct
.key);
oprot.writeFieldEnd();
if
(
struct
.value !=
null
) {
oprot.writeFieldBegin(VALUE_FIELD_DESC);
oprot.writeString(
struct
.value);
oprot.writeFieldEnd();
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
|
struct.validate()主要用来校验thrift文件中定义的required域即必传的值是不是有值,没有值就会抛出TProtocolException异常
1
2
3
4
5
6
7
|
public
void
validate() throws org.apache.thrift.TException {
// check for required fields
|