列表的节流(de)序列化

时间:2014-07-09 09:48:21

标签: java serialization thrift

在Thrift中,在对服务的方法调用的上下文中,列表可以直接用作参数或返回类型。如果您需要显式的对象(反)序列化,是否有一种方便的方法(在Java中)使用Thrift来(de)序列化List< TBase>而不必将其作为节俭IDL中的单独结构包装?

更具体地说,假设我已经在节俭中定义了

struct A {
    1: required long x;
    2: required long y;
}

我可以通过定义

来(de)序列化这些列表
struct ListOfA {
    1: required list<A> theList;
}

然后

ListOfA myList = ...
TSerializer serializer = new TSerializer();
byte[] mySerializedList = serializer.serialize(myList);

我的问题是,是否可以避免这种(略微不优雅的)额外结构的定义仅包含列表。

以下不起作用,因为TSerializer.serialize需要TBase

List<A> myList = ...   // List<A> instead of ListOfA
TSerializer serializer = new TSerializer();
byte[] mySerializedList = serializer.serialize(myList); //does not compile

在IDL中使用typedef已经有所帮助,但它们似乎没有被翻译成Java类

typedef list<A> ListOfA

=&GT; ListOfA未在生成的Java代码中定义。

1 个答案:

答案 0 :(得分:1)

  

我的问题是,是否可以避免这种(稍微不优雅的)额外结构的定义只包含列表

我建议相反:使用包装结构执行“低效”步骤。

Thrift允许任意数量的输入参数。但是,只能有一个返回值。没有varout参数或多个返回值之类的东西,因此您实际上限制为最多一个返回值以返回您需要返回的任何数据。

发挥作用的第二个方面是软版本化。 Thrift允许稍后增强接口和数据结构,而不会破坏旧服务或客户端。如果您决定这样做

struct Bar { /*some data*/ }

service Foo {
    list<Bar> GiveMeTheData()
}
你从根本上切断了这种机制。因为返回的list<Bar>无法使用新的其他成员进行扩展。在这种情况下,您将不得不添加另一个电话。

相比之下,通过使用包装struct,可以轻松扩展退货数据,而且付出的代价并不高:

struct Bar { /*some data*/ }

struct FooResult { 
  1: list<Bar>   list
  // new members here
}

service Foo {
    FooResult GiveMeTheData()
}

此外,后者还允许返回NULL列表,这对于第一个布局是不可能的。